Monday, August 4, 2025
14 changes · 17.0
Resolved issues and error corrections
Printing an Indian eWaybill no longer fails if the government API response does not include an expiry date. The report now safely skips formatting a missing date, helping users complete document printing even when external data is incomplete.
Original PR description
**Backport of https://github.com/odoo/odoo/commit/074a7b74be59a77cb161b7de33317c970416e08a** Steps to reproduce: Traceback occurs when printing the eWaybill. When the eWaybill expiry date is not present in the JSON response, any usage of date.strftime(...) caused a traceback. This fix ensures the date is checked before formatting to prevent such errors. Possible issue due to when API fails to return the expiry date opw-4991251 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix prevents an error when users clear the date while setting a remote work location from the calendar. It keeps the setup flow stable by avoiding date-based calculations when no date has been provided.
Original PR description
Currently, an error occurs if the date is missing when setting a work location via the calendar. **Steps to reproduce:** - Install the `hr` module. - Activate the **Remote Work** feature from the…
Currently, an error occurs if the date is missing when setting a work location via the calendar. **Steps to reproduce:** - Install the `hr` module. - Activate the **Remote Work** feature from the employee settings. - Open the Calendar (Month view), hover over a date, and click **Set Location** (or location icon). - Remove the date in the wizard and unfocus the field. **Error:** `AttributeError - 'bool' object has no attribute 'strftime'` This error occurs when the `date` field is `False`, and `_compute_day_week_string` attempts to call `strftime()` on a boolean value - [1]. After addressing the compute function issue, saving the record without a date results in another issue during employee location setup, where `weekday()` is called on a boolean - [2]. [1] - https://github.com/odoo/odoo/blob/e787d0a642bd710a8a80f8abc660c3ff4a385740/addons/hr_homeworking/wizard/homework_location_wizard.py#L25 [2] - https://github.com/odoo/odoo/blob/e787d0a642bd710a8a80f8abc660c3ff4a385740/addons/hr_homeworking/wizard/homework_location_wizard.py#L35 This commit prevent the computation if the `date` field is not set. Sentry - 6658596690
The Refresh button for counting records is now disabled when a filter/domain contains invalid input. This prevents users from triggering backend errors and makes the interface more stable when editing recipient rules.
Original PR description
Currently, an error occurs when clicking the **Refresh** button for computing record counts with an invalid field of the model. **Steps to reproduce:** - Install the `mass_mailing` module. - Create a…
Currently, an error occurs when clicking the **Refresh** button for computing record counts with an invalid field of the model.
**Steps to reproduce:**
- Install the `mass_mailing` module.
- Create a new mailing record with **Recipients: Contact**
- Add an invalid domain using the code editor (e.g., `[('test', '=', False)]`).
- Click the **Refresh** button below the editor.
- Observe the error in the back-end logs.
**Error:**
`ValueError: Invalid field res.country.country_id in condition ('country_id.name', '=', 'India')`
The error occurs because the system attempts to fetch the `country_id.name` field of the `res.country` model. During this process, a `KeyError` is encountered, which subsequently results in a `ValueError.`
This commit ensures that the **Refresh** button is disabled when the domain is invalid. This prevents the `search_count` method from being invoked through the UI with invalid input, avoiding the error.
Sentry - 6285599608, 6424158746, 6505582094, 6536603548, 6626159650, 6606355035
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis fixes an issue where newly created calendar meetings could be saved without properly linking to the selected contact. The change helps ensure meetings created from a contact record stay associated with that contact as expected.
Original PR description
To reproduce:
=============
- Pick any contact
- Click on meeting
- Select the time for the meeting with that contact
- Click on more options
- Add a meeting and save
- Click on meeting & contact
Problem:
========
- When creating calendar events, res_id=0 is passed in vals_list
- Events are created with res_id=0 instead of using default value
Solution:
=========
- Add separate handling for res_id in vals_list processing
- Apply defaults.get('res_id') when vals.get('res_id') is falsy
opw-4892445
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prIncoming return slips no longer display placeholder demo address text when a vendor warehouse has no linked contact. The slip now uses the receipt's contact information as a fallback, helping staff and partners see the correct destination on printed return documents.
Original PR description
Issue ----- Incoming return slips have a "Demo Address and Name" text instead of the correct destination address. <img width="928" height="658" alt="image"…
Issue ----- Incoming return slips have a "Demo Address and Name" text instead of the correct destination address. <img width="928" height="658" alt="image" src="https://github.com/user-attachments/assets/6ff0a5e7-f1ee-4faa-a22b-76ec8f2f7a28" /> Steps to reproduce ----- - Create a receipt for a product - Print its return slip Cause ----- By default, the address is taken from the pickings location_id -> warehouse_id -> partner_id. For incoming pickings, the warehouse is the vendor one, with no associated partner. In such cases, the partner can be found directly on the picking itself with the partner_id field. Note ----- To render t-fields, qweb first applies a `rsplit` before evaluating the expression, see https://github.com/odoo/odoo/blob/cb1c761777e84d96f82c4f754586795509ce1b3d/odoo/addons/base/models/ir_qweb.py#L2015-L2016 With this in mind, using parentheses and moving `.partner_id` outside of them seems like the most readable way to go about it. ----- Ticket: opw-4660716
The checkout flow now checks whether the related sales order still exists before continuing delivery steps. If the order was deleted after a canceled or failed payment, shoppers are redirected back to the shop instead of seeing an error.
Original PR description
This error occurs when there is no record of a sales order available for the ongoing order with a payment status of ``Canceled/Error``, and an attempt is made to deliver that order. Steps to…
This error occurs when there is no record of a sales order available for the ongoing order with a payment status of ``Canceled/Error``, and an attempt is made to deliver that order. Steps to reproduce: - Install the ``website_sale`` module - Invoicing > Configuration > Online Payments > Payment Providers - Activate ``Demo`` payment provider - Add any product to the cart > View Cart > Checkout - Choose payment method > Payment Status: ``Canceled/Error`` > Pay Now - Now duplicate the tab > Go to the first tab - eCommerce > orders > remove the ``Confirmed`` filter and delete the order that you have created - Go to the second tab > click on ``Skip`` Traceback: ``ValueError: Expected singleton: sale.order()`` When deleting an order during delivery because of payment status in ``Canceled/Error``, we encounter an issue at line [1] where the order appears empty. This leads to an error being raised due to the order's emptiness. This commit will resolve the above error by verifying if the order exists during delivery. If it doesn't, the system will redirect back to the shop. [1]: https://github.com/odoo/odoo/blob/0ed79a4cbd705daf3690bcc602c31cb3f6099bec/addons/delivery/models/delivery_carrier.py#L133 sentry-4961963900 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Creating a new scrap record no longer crashes when the configured scrap location has been disabled. This helps inventory users continue working safely and receive proper handling instead of an unexpected error.
Original PR description
This error occurs when the `Scrap Location` is disabled on a location, and we tried to create a New scrap record. Steps to reproduce: --- - Install `stock` module - Inventory > Configurations > Settings > Enable `Storage Locations` - Configurations > Locations > Remove Filter > Select `Virtual Locations/Scrap` - Disable `Is a Scrap Location` - Inventory > Operations > Scrap > New Scrap Traceback: --- `KeyError: 1` At [1], the `groups` result is empty because no location with `Scrap Location` enabled is found. As a result, `locations_per_company` is empty, and accessing `locations_per_company[scrap.company_id.id]` causes a KeyError. [1]- https://github.com/odoo/odoo/blob/3ddb91bf0e90177f12cec2c475ae57653c7032df/addons/stock/models/stock_scrap.py#L77-L85 sentry-6572853788 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
AsiaPay payments now show a clear warning when a selected currency is not supported instead of failing with an unexpected error. This helps businesses understand the issue immediately and avoid disrupted payment processing for unsupported currencies such as PKR.
Original PR description
This error occurs because the ``PKR`` currency is not present in the ``CURRENCY_MAPPING``. However, at [1], we are getting the ID of ``PKR``, which causes the error below to be raised. Traceback: ``KeyError: 'PKR'`` [1]- https://github.com/odoo/odoo/blob/8b035af881a72048027072743f7ba80accd73109/addons/payment_asiapay/models/payment_transaction.py#L91 sentry-5604749493 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Fixes an issue where changing a blog cover image or its filter could accidentally save internal cover template details into the page. This keeps website blog pages cleaner and prevents unwanted display or editing problems after saving.
Original PR description
Since summernote was replaced by the editor, the record cover template becomes `o_dirty` and therefore gets saved when a cover image is changed. This commit solves this by marking the record cover components readonly inside the DOM. Steps to reproduce: - install website_blog - set a blog cover image or specify its filter - save => The `record_cover` template was saved with the modifications, thus combining `t-att-style` and `style` attributes. task-jke Forward-Port-Of: odoo/odoo#219013
This fix prevents users from seeing a technical error when saving a view that contains invalid context syntax. Instead of triggering a traceback, Odoo can handle the validation problem more cleanly, improving reliability for administrators editing views.
Original PR description
When the user edits the view and adds context with invalid syntax, a traceback will appear. Steps to reproduce the error: - Go to Settings > Technical > Views > Open any view - Add context = "[]" or…
When the user edits the view and adds context with invalid syntax,
a traceback will appear.
Steps to reproduce the error:
- Go to Settings > Technical > Views > Open any view
- Add context = "[]" or context = "{a}" like this in the view
- Save
Traceback:
```
ValueError: Non-dict expression
File "odoo/addons/base/models/ir_ui_view.py", line 377, in _check_xml
view._validate_view(combined_arch, view.model)
File "odoo/addons/base/models/ir_ui_view.py", line 1464, in _validate_view
self._validate_attributes(node, name_manager, node_info)
File "odoo/addons/base/models/ir_ui_view.py", line 1789, in _validate_attributes
for key, val_ast in get_dict_asts(expr).items():
File "odoo/tools/view_validation.py", line 264, in get_dict_asts
raise ValueError("Non-dict expression")
AttributeError: 'NoneType' object has no attribute '__traceback__'
File "odoo/http.py", line 2383, in __call__
response = request._serve_db()
File "odoo/http.py", line 1913, in _serve_db
return self._transactioning(
File "odoo/http.py", line 1976, in _transactioning
return service_model.retrying(func, env=self.env)
File "odoo/service/model.py", line 134, in retrying
result = func()
File "odoo/http.py", line 1943, in _serve_ir_http
response = self.dispatcher.dispatch(rule.endpoint, args)
File "odoo/http.py", line 2187, in dispatch
result = self.request.registry['ir.http']._dispatch(endpoint)
File "odoo/addons/base/models/ir_http.py", line 227, in _dispatch
result = endpoint(**request.params)
File "odoo/http.py", line 757, in route_wrapper
result = endpoint(self, *args, **params_ok)
File "home/odoo/src/enterprise/saas-17.4/web_studio/controllers/main.py", line 699, in edit_view
self._set_studio_view(view, new_arch)
File "home/odoo/src/enterprise/saas-17.4/web_studio/controllers/main.py", line 459, in _set_studio_view
studio_view.arch_db = arch
File "odoo/fields.py", line 1378, in __set__
records.write({self.name: write_value})
File "home/odoo/src/enterprise/saas-17.4/web_studio/models/studio_mixin.py", line 33, in write
res = super(StudioMixin, self).write(vals)
File "odoo/addons/base/models/ir_ui_view.py", line 531, in write
res = super(View, self).write(self._compute_defaults(vals))
File "odoo/models.py", line 4582, in write
real_recs._validate_fields(vals, inverse_fields)
File "odoo/models.py", line 1513, in _validate_fields
check(self)
File "odoo/addons/base/models/ir_ui_view.py", line 416, in _check_xml
raise err.with_traceback(e.__context__.__traceback__) from None
```
https://github.com/odoo/odoo/blob/a32f78f93e0afaf997d90237795ca648661a88b0/odoo/addons/base/models/ir_ui_view.py#L416
Here, ```e.__context__``` is None because ```get_dict_asts``` raises the exception,
which clears exception context and prevents exception chaining.
so ```e.__context__``` remains unset.
So, it will lead to the above traceback.
sentry-4736234976
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThe website donation flow now handles cases where a visitor clicks Donate without entering an amount. This prevents an error page and keeps the donation experience clearer and more reliable.
Original PR description
When user clicks on the donate button without the amount,
A traceback will appear.
Steps to reproduce the error:
- Install ``website_payment`` and activate demo payment provider
- Go to Website > Drag and drop the donation button > Save
- Click on Donate Now > Click on custom amount box > Don't add any amount
- Click on Donate button
Traceback:
```
File "/home/odoo/src/odoo/addons/website_payment/controllers/portal.py", line 38, in donation_transaction
if float(amount) < float(minimum_amount):
TypeError: float() argument must be a string or a real number, not 'NoneType'
```
https://github.com/odoo/odoo/blob/f31a8d64d8447c516a2793705fb0b2d640289e85/addons/website_payment/controllers/portal.py#L38
Here, when user clicks on donate button without amount,
``amount`` will be None, so ``float(amount)`` will lead to the above Traceback.
sentry-6498712345
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prA test was added to ensure early payment discounts created during bank reconciliation receive the correct analytic distribution. This helps prevent reporting gaps where discounts were categorized properly during manual payments but not during bank reconciliation.
Original PR description
This commit adds a test for the following issue: - Configure an early discount payment term (e.g., 2/7 Net 30). - Configure the analytic distribution model with the account used when a discount is granted (e.g., 657000 on the BE fiscal position). - Create an invoice using the early discount payment term. - On bank reconciliation, register the transaction taking into account the early payment discount (e.g., 98% of the invoice amount_total). On the third line with account 657000, corresponding to the early discount payment, the analytic distribution model does not apply. In contrast, when manually registering a payment for the invoice, the analytic is correctly applied. community pr: https://github.com/odoo/odoo/pull/217933 opw-4868986
The accounting reports now handle a missing INR currency reference gracefully instead of showing an error. This prevents users from being blocked when opening the balance sheet after currency configuration data has been removed.
Original PR description
This error occurs when the user removes ``INR`` from the external identifier and attempts to access the balance sheet in accounting. Steps to reproduce: - Install ``account_reports`` module -…
This error occurs when the user removes ``INR`` from the external identifier and attempts to access the balance sheet in accounting.
Steps to reproduce:
- Install ``account_reports`` module
- Accounting > Configuration > Accounting > Currencies
- Search for ``INR`` and delete it
- Open Accounting /Reporting / Statement Reports / Balance sheet
Traceback :
``` KeyError: ('ir.model.data', <function IrModelData._xmlid_lookup at 0x7faa43a937f0>, 'base.INR')
File "odoo/tools/cache.py", line 103, in lookup
r = d[key]
File "<decorator-gen-5>", line 2, in __getitem__
File "odoo/tools/func.py", line 87, in locked
return func(inst, *args, **kwargs)
File "odoo/tools/lru.py", line 34, in __getitem__
a = self.d[obj]
ValueError: External ID not found in the system: base.INR
File "odoo/http.py", line 2251, in __call__
response = request._serve_db()
File "odoo/http.py", line 1827, in _serve_db
return self._transactioning(_serve_ir_http, readonly=ro)
File "odoo/http.py", line 1847, in _transactioning
return service_model.retrying(func, env=self.env)
File "odoo/service/model.py", line 134, in retrying
result = func()
File "odoo/http.py", line 1825, in _serve_ir_http
return self._serve_ir_http(rule, args)
File "odoo/http.py", line 1832, in _serve_ir_http
response = self.dispatcher.dispatch(rule.endpoint, args)
File "odoo/http.py", line 2057, in dispatch
result = self.request.registry['ir.http']._dispatch(endpoint)
File "odoo/addons/base/models/ir_http.py", line 220, in _dispatch
result = endpoint(**request.params)
File "odoo/http.py", line 739, in route_wrapper
result = endpoint(self, *args, **params_ok)
File "addons/web/controllers/dataset.py", line 38, in call_kw
return self._call_kw(model, method, args, kwargs)
File "addons/web/controllers/dataset.py", line 34, in _call_kw
return call_kw(request.env[model], method, args, kwargs)
File "odoo/api.py", line 458, in call_kw
result = getattr(recs, name)(*args, **kwargs)
File "home/odoo/src/enterprise/saas-17.2/account_reports/models/account_report.py", line 1663, in get_options
initializer(options, previous_options=previous_options)
File "home/odoo/src/enterprise/saas-17.2/account_reports/models/account_report.py", line 1224, in _init_options_rounding_unit
options['rounding_unit_names'] = self._get_rounding_unit_names()
File "home/odoo/src/enterprise/saas-17.2/account_reports/models/account_report.py", line 1236, in _get_rounding_unit_names
if (self.env.company.currency_id == self.env.ref('base.INR')):
File "odoo/api.py", line 584, in ref
res_model, res_id = self['ir.model.data']._xmlid_to_res_model_res_id(
File "odoo/addons/base/models/ir_model.py", line 2187, in _xmlid_to_res_model_res_id
return self._xmlid_lookup(xmlid)
File "<decorator-gen-43>", line 2, in _xmlid_lookup
File "odoo/tools/cache.py", line 110, in lookup
value = d[key] = self.method(*args, **kwargs)
File "odoo/addons/base/models/ir_model.py", line 2180, in _xmlid_lookup
raise ValueError('External ID not found in the system: %s' % xmlid)
```
The error is coming from line[1] as it's referring to a record with the external identifier ``INR`` in the ``base`` module of Odoo but we are unable to find the identifier.
This commit will fix the above error by returning the 'None' if the external identifier is not found.
[1] : https://github.com/odoo/enterprise/blob/8f775d38f2f649837bdf0beca6f4be8fb574e436/account_reports/models/account_report.py#L1234
sentry - 5176020255Users who still have a deleted spreadsheet open will no longer see a technical error when they refresh or reconnect. The system now handles the missing spreadsheet gracefully, improving reliability during collaborative spreadsheet use.
Original PR description
When Spreadsheet is deleted and user tries to access the spreadsheet, a traceback will appear. Steps to reproduce the error: - Go to documents > Create New spreadsheet > open that spreadsheet - Now…
When Spreadsheet is deleted and user tries to access the spreadsheet,
a traceback will appear.
Steps to reproduce the error:
- Go to documents > Create New spreadsheet > open that spreadsheet
- Now login with another user > open that spreadsheet
- Delete the spreadsheet > Try to access the spreadsheet from the second user >
Refresh the page
Traceback:
```
MissingError: Record does not exist or has been deleted.
(Record: documents.document(263,), User: 2)
File "addons/bus/websocket.py", line 935, in _serve_forever
req.serve_websocket_message(message)
File "addons/bus/websocket.py", line 770, in serve_websocket_message
service_model.retrying(
File "odoo/service/model.py", line 134, in retrying
result = func()
File "addons/bus/websocket.py", line 784, in _serve_ir_websocket
self.env['ir.websocket']._subscribe(data)
File "addons/bus/models/ir_websocket.py", line 42, in _subscribe
channels = set(self._build_bus_channel_list(data['channels']))
File "home/odoo/src/enterprise/saas-17.2/spreadsheet_edition/models/ir_websocket.py", line 13, in _build_bus_channel_list
channels = self._add_spreadsheet_collaborative_bus_channels(channels)
File "home/odoo/src/enterprise/saas-17.2/spreadsheet_edition/models/ir_websocket.py", line 34, in _add_spreadsheet_collaborative_bus_channels
record = self._check_spreadsheet_channel(channel)
File "home/odoo/src/enterprise/saas-17.2/spreadsheet_edition/models/ir_websocket.py", line 55, in _check_spreadsheet_channel
access = record._check_collaborative_spreadsheet_access(
File "home/odoo/src/enterprise/saas-17.2/spreadsheet_edition/models/spreadsheet_mixin.py", line 308, in _check_collaborative_spreadsheet_access
self.check_access_rule(operation)
File "odoo/models.py", line 4175, in check_access_rule
invalid = self - self._filter_access_rules_python(operation)
File "odoo/models.py", line 4225, in _filter_access_rules_python
return self.sudo().filtered_domain(dom or [])
File "odoo/models.py", line 6201, in filtered_domain
data = record.mapped(key)
File "odoo/models.py", line 6089, in mapped
recs = recs._fields[name].mapped(recs)
File "odoo/fields.py", line 1335, in mapped
self.__get__(first(remaining), type(remaining))
File "odoo/fields.py", line 2954, in __get__
return super().__get__(records, owner)
File "odoo/fields.py", line 1242, in __get__
raise MissingError("\n".join([
```
Solution:
A try-catch is used to catch MissingError when the spreadsheet is deleted.
sentry-5000900649