Daily updates from Odoo
Wednesday, September 3, 2025
1 change
Resolved issues and error corrections
This fix prevents a timing issue where newly uploaded attachments could be deleted by background cleanup before their database record was fully created. It improves reliability for users downloading files such as documents, PDFs, and payslips.
Original PR description
Should ideally land in 13.0... Let's merge it in 18.3 where we need it first... Then backport it to 16.0 if deemed useful/necessary. --- There is a race condition between `ir.attachment.create` and…
Should ideally land in 13.0... Let's merge it in 18.3 where we need it first... Then backport it to 16.0 if deemed useful/necessary.
---
There is a race condition between `ir.attachment.create` and `ir.attachment._gc_file_store` that can lead to the creation of an attachment with no related file in the file store.
Race
----
The race runs as follow:
1) `_gc_file_store` acquires a write exlusif lock on the ir_attachment table, but is interrupted by the OS before it can load the file gc checklist.
2) `create` kicks in, write a new file on file-system, adds an entry in the checklist, but can't create the ir.attachment record yet as the table is locked.
3) `_gc_file_store` resumes, load the checklist, see that `create`'s file as no attachment and removes it. It then releases the write exclusif table lock.
4) `create` resumes, it creates the `ir.attachment` record.
Subsequent access on the ir.attachment created record `raw` or `datas` fields fails because the file doesn't exist on disk.
Test
----
https://gist.github.com/Julien00859/512cfbad47c15febbfd667a017df7c8b
The `test_attachment_concurrency_create_gc` test reproduces the above steps to reproduce the bug. It does so by mocking the appropriate functions and using `threading.Event` to synchronize the execution plan between the two threads. Run it using the following command:
--test-tags database_breaking.test_attachment_concurrency_create_gc
It is database breaking because the ir.attachment file created during the test may not cleaned after the test run (in case the power goes down at the wrong moment).
Description
-----------
The bug was introduced by commit afdfdbfa5b36b in 13.0. Before that commit the create override in ir.attachment would first create the record, and only then write the file on disk. This way the `create` function acquired first a row exclusif lock and only then wrote the file and the checklist.
That the error went undercover for several years can be explained as follow:
1. The ir.autovacuum model and its cron has been unreliable for many years, it was often reported that the `_gc_file_store` (being the last in the list) did not run.
2. That the cron did not run made for a huge checklist that couldn't be processed all at once.
3. The cron usually only run once per night, when there are less people connected on the database to create attachments.
4. Finally, embarassing, we did discard some "missing file" reports and instead blamed the customers who reported them.
That we discover the error now is another chain of events:
1. The ir.autovacuum model now makes an advanced usage of the cron progress API. The cron is now automatically scheduled to run again "as soon as possible" when an exception occured in one of the `@api.autovacuum` methods.
2. The documents autovacuum is failing in 18.3 100% of the time (this is being addressed in another PR). This forces the "run again as soon as possible" condition permanent. The cron is basically always running.
3. The Odoo employees are all paid at the same time, and we all receive a PDF payslip as attachment. As many attachments as there are employees are created at a same time.
Some of us couldn't download our August payslip :-(