-
-
Notifications
You must be signed in to change notification settings - Fork 8.4k
[🐛 Bug]: OSError Text file busy on .cache/selenium #13511
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@anteph, thank you for creating this issue. We will troubleshoot it as soon as we can. Info for maintainersTriage this issue by using labels.
If information is missing, add a helpful comment and then
If the issue is a question, add the
If the issue is valid but there is no time to troubleshoot it, consider adding the
If the issue requires changes or fixes from an external project (e.g., ChromeDriver, GeckoDriver, MSEdgeDriver, W3C),
add the applicable
After troubleshooting the issue, please add the Thank you! |
Logs (or even a stack trace) would help provide context for what is happening with this exception occurs. Without more info, I'm not sure how this would happen. Selenium ensures that each driver constructor goes through Selenium Manager which makes sure the right driver is available for use. I'm not sure how Selenium Manager on the one hand tells the code which driver to use at the same time that it isn't ready for use. |
Here is the stack trace:
Unfortunately I don't have any logs as I didn't find a way yet to reproduce it, if I manage to I'll try to get some logs. Please let me know if I can provide any additional context that may be helpul. Thanks! |
@bonigarcia this error seems to indicate that when running in parallel :
Any ideas how this might happen? Would ttl affect it somehow? |
In Ruby, we were able to pre-download the webdriver by running the following code before running Selenium in multiple threads.
The code to do the same thing in Python probably looks something like this.
I would be happy if the pre-download procedure is documented. |
Selenium Manager never redownloads the driver once it is in the cache. An exception will happen if the cache is refreshed each time, which I suppose is very unlike (e.g., So, the first thing will be trying to understand why this issue happens. I don't see clearly that this is related to the Rust side. First, when a similar error occurs in Rust, the error message is Second, I am not familiar with the Python implementation, but the error traces seem to indicate it happens when the chromedriver process is started. If that is true, I believe it means that Selenium Manager has finished its job. Regarding the TTL, it has nothing to do with it (see doc). I looked for this issue on the Web, and it has been reported other times, e.g.: https://stackoverflow.com/questions/62072978/chromedriver-text-file-busy |
From what I was able to determine, this issue is non-deterministic but when it happens, it happens when a new pod is launched. This means that effectively the cache is empty. I've tested myself launching a new instance of the container and I can see that the cache folder is empty. Then I instantiate the web driver for the first time and the cache gets filled. In my use case, since I have different processes being launched in the same pod, isn't it possible that two of them check the cache in parallel, see that the folder is empty, and then try to write to the cache at the same time? Since these are different processes and not threads, I think any underlying thread based synchronization mechanisms wouldn't work (assuming something such as a mutex could potentially be in use to prevent such a race condition)?
I get the Text file busy (error 26). The error message string is not exactly the same, but maybe it is something on the python side wrapping an OS error differently? I'm not very familiar with how Python bubbles up any error returned by a subprocess call, but at least the OS error seems to be the same. Not sure if this would change anything, but I'm pre-installing the chrome driver in the image in usr/bin/chromedriver. |
Yes, I believe that is possible. I'm trying to reproduce it on my side by using a concurrent creation of Selenium sessions (using Selenium 4.17 and an empty cache), but I still never experienced it. It would help if this issue could be reproduced somehow. Also, it will help to gather the complete logs when the error happens. @anteph This is the doc to gather all logs; thanks: https://www.selenium.dev/documentation/webdriver/troubleshooting/logging/ |
@masato-hi the procedure is going to change in the next release, and I will document that. |
@bonigarcia I've enabled the logs but haven't been able to reproduce it again (the incidence of this was quite low). I'll share if I manage to reproduce it again, but please feel free to close the ticket whenever you see fit. As a workaround I've simply added a retry in my application. Thanks! |
Hi 👋 I'm running automated tests with I was able to reproduce the issue with logs enabled, hope it helps:
|
Thanks for the logs, @igorpek. What I can see there is that Selenium-Manager works as expected: it downloads the driver and reports its path to the bindings:
I'm not sure, but maybe the problem happens when different processes try to write the same file in parallel. In that case, I don't know the best solution. In Slack, Simon told me about using a lock mechanism based on a known port called SocketLock:
But I believe that solution can bring another problem. What if another application uses the chosen port (7055 in the previous implementation)? @titusfortner: Any idea? |
An alternative idea would be using a file lock. There are some Rust crates about that, but I would need to look into that. |
Hello, I have the same problem. It started appearing after we decided to stop downloading a certain version of the chrome driver and started using Selenium Manager. First we download the latest version of chrome, the rest is done by the Selenium manager.
|
So we think this is Selenium Bindings running in different processes each running an instance of selenium manager which causes a race condition on which process can download the driver to that location... I'm assuming that rust downloads it and then sets it to executable or something. Is it possible for the rust code to catch that error and then wait for the file at that location to be ready and then return it? Alternately we can put that logic in the bindings.... |
I tried reproducing this by running 100 SM processes and I don't see any errors. Is this still a problem?
|
I'm still able to reproduce the issue by running 8 tests in parallel via
|
@igorpek Do you only see this on CircleCI or locally as well? |
@p0deje it seems I cannot reproduce it locally atm. |
As discussed with @bonigarcia, he'll try implementing a file-locking mechanism and then we'll share the preview build here so you can test it. // cc @titusfortner |
Hello, I am facing the same issue using Robot Framework with Selenium on Gitlab pipeline, The issue exist when I run tests in Parallel using Pabot, the setup of opening the browser is failling
|
Same as @mgrissa94, facing this issue right now in Robot Framework when running test in Parallel using Pabot. |
I implemented a fix for this issue. It would be very helpful if someone facing this problem could try the new Selenium Manager binary. It can be downloaded from the following page -thanks! https://github.com/SeleniumHQ/selenium/actions/runs/12325569526 |
Update: Get the latest Selenium Manager binaries from here: https://github.com/SeleniumHQ/selenium/actions/runs/12333312099 |
I tried out new Selenium Manager version ( I ran 8 tests in parallel (on CircleCI) and:
|
Many thanks for confirming, @igorpek! The fix is merged now. It will be shipped with Selenium 4.28. |
…eniumHQ#13511 and SeleniumHQ#13686) * [rust] Use file lock to protect concurrent accesses to cache * [rust] Fix several problems related to file manipulation * [rust] Improve logic for handling unstable edge bad links * [rust] Ensure lock file exists and content of target folder after acquiring lock * [rust] Refactor lock logic in a separate module * [rust] Acquire file lock before downloading driver and browser
This issue has been automatically locked since there has not been any recent activity since it was closed. Please open a new issue for related bugs. |
What happened?
Hello!
I'm using Selenium with Chrome driver to download some web pages. I'm running the browser in headless mode.
This piece of code is very basic and roughly like:
So, nothing special about it I believe.
The bit of the application that uses Selenium is running on Celery. The Celery worker is using a fork model, meaning that I have couple of processes (not threads) in each worker.
Sporadically, I've been seeing an OSError: text file busy on ~/.cache/selenium/chromedriver/linux64/121.0.6167.85/chromedriver.
The issue always occurs on the instantiation of the driver:
driver = webdriver.Chrome()
A couple of observations:
Given this seems to happen only once when a new pod launches, under load, and never repeats again, and that it happens on the instantiation of the driver, my suspicion is that there is some race condition on the Selenium Manager. As far as I've understood, Selenium Manager is the piece that is responsible for checking if the Chrome Driver .exe is already in the cache and if not, copy it to there. Maybe two processes are looking to the folder at the same time, see no .exe, and both try to copy it to there, causing the issue?
I've also seen this issue recently when running some of my unit tests on the same logic from above (although in this case I'm testing directly the function that downloads the pages, not the celery worker). But again, seems to be some parallelization related issue.
I've seen a couple of closed issues which mention a similar text file busy error, but they are closed by now and I think they are not exactly the same use case, but I apologize if I misunderstood and this is related.
Thank you :)
How can we reproduce the issue?
Relevant log output
I'm not collecting any logs, but I think the exception mentioned above is more relevant.
Operating System
Linux - Debian 11 (running in Docker)
Selenium version
Python - 4.17.2
What are the browser(s) and version(s) where you see this issue?
Chrome 121.0.6167.85
What are the browser driver(s) and version(s) where you see this issue?
Chrome Driver 121.0.6167.85
Are you using Selenium Grid?
No
The text was updated successfully, but these errors were encountered: