Wednesday, September 23, 2026
23 changes · master
Resolved issues and error corrections
The Odoo Gmail plugin was updated to use the correct system setting lookup for newer Odoo versions. This prevents an error that could block users from authenticating with Odoo through Gmail.
Original PR description
In version 19.1+, the ir.config_parameter model no longer has the function get_param. Instead you use get_int, get_str, etc. This was causing a traceback in auth_access_token when a user tries to authenticate with Odoo via the Odoo gmail plugin. Forward-Port-Of: odoo/odoo#289957
Live Chat rules now reject invalid URL matching patterns when they are saved. This prevents website visitors from triggering errors when Live Chat loads and helps administrators catch configuration mistakes earlier.
Original PR description
Currently, an error occurs when a user opens the website and Live Chat is initialized with an invalid URL regex. Steps to Reproduce: - Install `website_livechat` without demo data. - Open `Live Chat`…
Currently, an error occurs when a user opens the website and Live Chat is initialized with an invalid URL regex. Steps to Reproduce: - Install `website_livechat` without demo data. - Open `Live Chat` and, in the `YourWebsite.com` channel, click the `three-dot` menu and select `Configure Channel`. - Go to the `Rules` tab. - Add a rule, select `Welcome Bot` in `Chatbot`, and set an invalid regex such as `*` in `URL Regex` and save. - Click `Join Channel`. - Open the `website`. `re.PatternError: nothing to repeat at position 0 when serializing dict item 'result' ` - when `URL Regex is '['` `re.error: unterminated character set at position 0 when serializing dict item 'result'` When a user opens the website, Live Chat is initialized by checking operator availability and finding the matching country/URL rule [1]. The rule matching checks whether `regex_url` matches the current page URL. It uses `re.search()` [2], which compiles the regex pattern before searching. If `regex_url` contains an invalid pattern such as `*`, `re.search()` raises `nothing to repeat at position 0` because `*` must follow a preceding regex element. Similarly, `[` starts a character set (`[...]`) but has no closing `]`, causing `unterminated character set at position 0`. This commit adds a constraint to validate `regex_url` and reject invalid regex patterns when creating or updating Live Chat rules. [1]- https://github.com/odoo/odoo/blob/f962f1eccecfdbc95375f795174c8f687459b521/addons/im_livechat/controllers/main.py#L87 [2]- https://github.com/odoo/odoo/blob/f962f1eccecfdbc95375f795174c8f687459b521/addons/im_livechat/models/im_livechat_channel.py#L387 sentry-7679767396 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#283545
This fixes a crash that could occur when opening an email message containing an embedded code block in the chatter. Odoo now avoids applying code syntax highlighting inside incoming email bodies, keeping those messages readable and preventing the chatter from failing to load.
Original PR description
**Steps to reproduce:** - Receive a mail with an embedded code block - Open a chatter containing this message - Error: "Cannot mount a component on a detached dom node" **Issue:** Mail message are…
**Steps to reproduce:**
- Receive a mail with an embedded code block
- Open a chatter containing this message
- Error: "Cannot mount a component on a detached dom node"
**Issue:**
Mail message are rendered with a shadow dom body and isolated from surrounding styling.
```xml
<div class="o-mail-Message-shadowBody overflow-x-auto" t-if="this.message.message_type and this.message.message_type.includes('email')" t-custom-ref="shadowBody"/>
```
Then in `useLayoutEffect` parent element is created for the shadow root and the message body is created:
```js
const bodyEl = createElementWithContent(
"span",
this.message.showTranslation
? this.message.richTranslationValue
: this.props.messageSearch?.highlight(this.message.richBody) ??
this.message.richBody
);
const roots = this.prepareMessageBody(bodyEl) ?? [];
this.shadowRoot.appendChild(bodyEl);
```
But after [1] we have `return this.renderEmbeddedCodeBlocks(bodyEl);` which calls:
```js
const { root, mountPromise } = mountComponent(...);
```
And root creation fails as the element is not on the shadow root yet (due to `validateTarget` and `isAttachedToDocument`).
```js
const root = app.createRoot(Component, { props, env });
```
But even if we have the element directly added on the `shadowRoot` the highlighting styling won't be applied properly without all the needed assets.
**Fix:**
Prevent `ReadonlySyntaxHighlightingComponent` for incoming email body.
Doesn't seem worth to try to load the needed css/style elements in the shadow root.
[1] https://github.com/odoo/odoo/commit/8fa3cc31e8b81645d40b5d09c925b57d2c0558ab
opw-6463735
Forward-Port-Of: odoo/odoo#288136
Forward-Port-Of: odoo/odoo#287977When Knowledge is turned off for a Helpdesk Team, the related article is now unlinked automatically. This prevents articles from remaining blocked as “in use” and makes any archive or unpublish warning clearer by naming the affected teams.
Original PR description
Before this commit, unchecking the "Knowledge" option on a Helpdesk Team did not remove the link to the associated article. As a result, users could not delete or archive the article later because it was still considered "in use" by the team. This commit ensures: - The linked article is automatically removed from the Helpdesk Team when the "Knowledge" option is disabled. - The validation error message displayed when archiving or unpublishing a linked article is improved to explicitly list the specific Helpdesk Team(s) involved. task-5075527
The AI website builder now prioritizes Unsplash images when credentials are available, using default images as a fallback. This avoids unnecessary AI image generation unless the user specifically asks for it, reducing delays and costs.
Original PR description
Currently we have an issue where the AI will ignore unsplash credentials because it thinks that it will be able to make better images using the generation. However, this is slow and costly. This commit fixes the prompt to tell the AI precisely what to do i.e. always use unsplash if possible otherwise fall back to default images. If the user specifically asks for ai generated images, then we will prioritise that. task-6591258 Forward-Port-Of: odoo/enterprise#132517
This fixes an issue where users could not validate subcontracted purchase receipts after partially processing them in the Barcode app. The change keeps the related manufacturing order aligned when barcode operations split quantities, preventing validation errors and reducing disruption in receiving workflows.
Original PR description
eproduction steps: - MRP subcontracting + purchase - Subcontracted product with BOM - Create PO with a qty > 1 for this product - Go into barcode - Scan > 0 and < all of the expected quantity - Back…
eproduction steps: - MRP subcontracting + purchase - Subcontracted product with BOM - Create PO with a qty > 1 for this product - Go into barcode - Scan > 0 and < all of the expected quantity - Back out of barcode - Click validate -> Error **OR** Go back into barcode, attempt to validate -> Error Added the StockMove and StockPicking classes to stock_barcode_mrp_subcontracting to extend functions `_subcontracted_produce`, `_clean_merged`, and `split_uncompleted_moves` to use a new context flag, `keep_subcontract_production`. When this flag is set, the move Barcode creates from the split keeps the MO of the move it was split from rather than splitting the MO in two, gives that link up before it is merged away so its cancellation does not cancel the MO, and the MO quantity is resynced with the merged move afterwards. Error thrown here: https://github.com/odoo/odoo/blob/f84eeb3ed1421e0cc07c906ff6444734dc01d35f/addons/mrp_subcontracting/models/stock_move.py#L248 opw-6428928 Forward-Port-Of: odoo/enterprise#131459
This update fixes how Belgian payroll calculates basic salary when an employee has multiple contract versions in the same month. Payroll now applies the 50% rule consistently, reducing the risk of incorrect salary amounts in affected payslips.
Original PR description
there is a problem that we If we have two versions in the same month, we always follow the second option of the 50% rule. This is because the theoretical hours are calculated for the whole month, but the paid amount is calculated separately for each version. We fixed this by checking If unpaid hours > paid hours, salary is calculated by multiplying the hourly rate by the total hours. Otherwise, salary is calculated as the base wage minus (unpaid hours × hourly rate). And return back the test to what exist before the task with id : 6260378 task Id: 6515980 Forward-Port-Of: odoo/enterprise#129985
This pull request mainly tidies and fixes how document records are updated, making future changes safer and easier to maintain. It also includes several payroll, reporting, translation, leave planning, and interface polish fixes that improve reliability and consistency for users.
Original PR description
* 238 lines is just too long. * Prepare adding more writing logic for 6310302. * Remove obsolete archiving methods. Task-6443853
Settings no longer crashes when a company cannot access certain WhatsApp planning templates. The update only assigns templates to companies that are allowed to use them and treats inaccessible templates as not configured, keeping multi-company settings usable.
Original PR description
Purpose: Settings crashed with an `AccessError` for a company that can't read the planning templates. Specifications: At install, the planning templates get the first WhatsApp account found, which is often allowed for one company only. The post init hook and the field defaults set these templates on every company, so the other companies couldn't read them and Settings raised. The hook now only sets a template on the companies its account allows, and the defaults only set a template without account, since a new company isn't on any account yet. The account of a template can still change later, so Settings shows a template the user can't read as not configured, and the wizard clears it. Forward-Port-Of: odoo/enterprise#131831
Resetting an expense report to draft now also clears Studio approval records for posting journal entries. This prevents old approvals from being reused, ensuring the report must be approved again before it can be posted.
Original PR description
Currently, when resetting to draft an expense sheet, approval steps added with studio are not reset, silently granting the change Steps to reproduce: - In Studio, add an approval rule on the "Post Journal Entries" button on expense sheet - Create an expense report, submit it and approve it - Click "Post Journal Entries" and approve approve it - Open the journal entry and reset it to draft - Back to the expense sheet, reset it to draft too Issue: The "Post Journal Entries" button is still approved, showing the previous approver with the same approval date. Analysis: Approval entries are dropped on state change by a base automation that Studio builds when the rule is created. However it is only done for sale order, account move and purchase order. opw-6530689 Forward-Port-Of: odoo/enterprise#130692
This update corrects missing setup details in several Odoo components that could cause screens or actions to crash after a platform compatibility change. It helps keep affected areas such as Sign, Barcode, VoIP, spreadsheets, accounting reports, AI discussions, and Peru POS invoicing working reliably.
Original PR description
Forward-Port-Of: odoo/enterprise#132379
Users can now provide the intended language for voice transcription in the AI feature. This helps prevent speech from being transcribed in the wrong language, reducing confusing or incorrect results.
Original PR description
Prior to this commit, it was not possible to specify a transcription language. This could lead to glitches when the model would transcribe the user's voice in an improper language. Forward-Port-Of: odoo/enterprise#132534
Manufacturing work order barcode sheets were updated with smaller barcodes and wider spacing to reduce scanning mistakes on the shop floor. The barcode generation setup was also streamlined so future updates can be maintained more consistently.
Original PR description
Shrink barcodes and increase their spacings to avoid mistakes when scanning. Externalize make_sheet function to avoid code duplication. Allow to insert a blank row for more spacing through `blank_middle_column` parameter. Forward-Port-Of: odoo/enterprise#132432
This fix prevents Kenyan eTIMS invoice numbering from moving backwards after certain failed submissions. It reduces the risk of two invoices sharing the same eTIMS number, helping avoid filing mismatches and incorrect receipt details.
Original PR description
Give an eTIMS invoice number back to the sequence only when the failing call is the one that took it, and only when it is still the last one handed out. When sending a customer invoice fails with anything other than a timeout, the number is given back so that it is not consumed for nothing. current issue: - send an invoice, let it time out, so it keeps number N - send other invoices, so the sequence moves past N - send the first one again and let it fail with a non-timeout error - the sequence drops by one and the next invoice sent reuses a number Both documents then sit under the same number. On its next attempt the one that was never accepted finds the other one's filing through selectInvoiceDetails and copies its receipt details. opw-6502563 Forward-Port-Of: odoo/enterprise#131790 Forward-Port-Of: odoo/enterprise#129994
Ecuadorian point-of-sale orders now keep the user's choice when they uncheck "Invoice" during payment. This prevents unwanted invoices from being created and sent to the tax authority after order validation, especially when orders are reloaded through kitchen printer flows or feedback screen navigation.
Original PR description
Steps to reproduce: - Ecuadorian company, PoS with a preparation printer (or use the "Back" button on the feedback screen) - Open a session, add a product, go to the payment screen - Select a…
Steps to reproduce: - Ecuadorian company, PoS with a preparation printer (or use the "Back" button on the feedback screen) - Open a session, add a product, go to the payment screen - Select a customer, uncheck "Invoice", pay in cash and validate Issue: An invoice is created and sent to the SRI although "Invoice" was unchecked. Cause: l10n_ec_edi_pos patches PosOrder.setup() to force to_invoice = true. setup() runs not only on creation but every time the record is reloaded from the server, so the sync done at validation flips the flag back to true in the browser. Since the paid order can now be re-synced after validation (kitchen printer, "Back" on the feedback screen), the server processes it in process_saved_payments, writes to_invoice = True and generates the invoice. Fix: Only apply the Ecuadorian default when the loaded values carry no to_invoice, i.e. for a newly created order. Reloaded records keep the value the user chose. opw-6572987 Forward-Port-Of: odoo/enterprise#131612
The AI website builder now saves custom styling to the correct website and better checks style code before saving. This prevents broken pages and errors when users ask the AI to apply visual changes such as button colors or background images.
Original PR description
[FIX] ai_website: save custom css scoped Before this commit, if you had multiple websites, AI wouldn't save custom css in the correct website's bundles, which caused the following broken flow: - open…
[FIX] ai_website: save custom css scoped
Before this commit, if you had multiple websites, AI wouldn't save
custom css in the correct website's bundles, which caused the following
broken flow:
- open css editor, make any changes, and save it
- open the AI website builder agent and ask it to make all buttons red,
writing a custom css for that
=> you get a traceback, and after reloading your website is broken.
Note that this isn't an issue in 20.0 as this behavior has been changed.
Related to task-6578231
---
[FIX] ai_website: validate custom SCSS with bundle url rewriting
When AI used url($var) in scss, it would break the style compilation and
display an error. This happened because compiling replaced relative urls
with the absolute path. It wasn't caught before saving the custom css,
because we preprocessed css content inline, which doesn't rewrite
relative url()s.
To directly check it, you can just ask it to save this custom css:
`'$img: "a.png"; #test { background: url($img); }'`
=> Style compilation will fail.
Also, this commit updates some already present nested `with` statements
in tests to remove Ruff warnings.
task-6578231
Forward-Port-Of: odoo/enterprise#132463
Forward-Port-Of: odoo/enterprise#131954This fix ensures remaining monthly pay balances are applied to the correct worked day line in Belgian payroll. It improves payroll amount distribution accuracy, especially when multiple worked day entries are present.
Original PR description
For monthly pay, the amount regularization (remaining balance) was incorrectly applied to the worked day line with the maximum hours. It must be applied to the first worked day line instead to ensure proper amount distribution. This commit: - Modifies `_l10n_be_get_paid_work_days` to sort `paid_worked_days` by `code` first, and `number_of_hours` (descending) second. This ensures the correct code is targeted while safely handling multiple lines with the same code. - Updates test assertions to match the newly expected distribution. Task: 6512884 Forward-Port-Of: odoo/enterprise#131884
This fix prevents shared appointment resources from being overbooked when bookings are created from the backend Gantt view. It avoids invalid capacity calculations that could block customers from completing website appointments, improving booking reliability.
Original PR description
**Steps to reproduce:** - Install Appointment app - Create an appointment type based on resources, auto-assigned, with two shareable resources linked together - Set the first resource's capacity to 3…
**Steps to reproduce:**
- Install Appointment app
- Create an appointment type based on resources, auto-assigned, with two shareable resources linked together
- Set the first resource's capacity to 3 and the second resource's capacity to 4
- From the backend Gantt view, create a booking for 2 people on the first resource
- Create a second booking for 2 people on the same resource, at the same date and time
- First resource is now overbooked with reserved capacity of 4 out of 3
- Try to create an appointment from the website
- Error: "The capacity reserved should be positive."
**Issue:**
When bookings are created from the backend gantt view, the selected resource can be overbooked even if another linked resource still has available capacity.
Then when trying to book an appointment the new booking lines will trigger this constraint:
```py
_check_capacity_reserved = models.Constraint(
'CHECK(capacity_reserved >= 0)',
"The capacity reserved should be positive.",
)
```
This is caused by the negative values in:
```py
booking_line_values = []
if appointment_type.schedule_based_on == 'resources':
capacity_to_assign = asked_capacity
for resource in resources:
resource_remaining_capacity = resources_remaining_capacity.get(resource)
new_capacity_reserved = min(resource_remaining_capacity, capacity_to_assign, resource.capacity)
capacity_to_assign -= new_capacity_reserved
booking_line_values.append({
'appointment_resource_id': resource.id,
'capacity_reserved': new_capacity_reserved,
'capacity_used': new_capacity_reserved if resource.shareable and appointment_type.resource_manage_capacity else resource.capacity,
})
```
**Fix:**
Avoid negative remaining value in resource booking when computing available slots.
Note: Tried to take the capacity already used by overlapping bookings into account when assigning resource booking lines from the backend gantt view. And also force linked_resources booking when trying to book more
than the total capacity to properly dispatch as many slots as possible. But it was breaking `appointment_google_reserve` tests.
opw-6503147
Forward-Port-Of: odoo/enterprise#132484
Forward-Port-Of: odoo/enterprise#130520Vendor bill lines now only allow users to choose purchase order lines from confirmed purchase orders. This prevents draft or unconfirmed RFQs from being accidentally linked to bills, improving purchasing and billing accuracy.
Original PR description
Issue Before This Commit: ========================= Currently, the Purchase Order Line field on the vendor bill line allows users to select purchase order lines regardless of the purchase order…
Issue Before This Commit: ========================= Currently, the Purchase Order Line field on the vendor bill line allows users to select purchase order lines regardless of the purchase order state. As a result, lines from purchase orders that are not confirmed can also be selected and linked to vendor bill lines. Steps to Reproduce: =================== - Install Purchase and create an RFQ. - Create a vendor bill for the same vendor. - Add a bill line and enable the Purchase Order column. - Open the dropdown of the Purchase Order Line field. - Observe that lines from unconfirmed purchase orders are available for selection. Cause of the Issue: ==================== This [PR](https://github.com/odoo/odoo/pull/266003) made Purchase Order lines selectable directly on bill lines, but the selection domain did not restrict the lines to confirmed purchase orders. Therefore, lines from unconfirmed purchase orders remained available for selection. After This Commit: ================== Only Purchase Order lines from confirmed purchase orders are selectable on vendor bill lines. Forward-Port-Of: odoo/odoo#288858
This fixes a crash that could occur when creating multiple records from popovers that include translatable fields, such as in calendar views. Translation controls are now hidden where they do not apply, making the popover more reliable for users.
Original PR description
When a translatable field is displayed in the multi create popover (e.g. in a calendar view with a `multi_create_view`), the rendering of the popover crashes when the props are validated (in debug…
When a translatable field is displayed in the multi create popover (e.g. in a calendar view with a `multi_create_view`), the rendering of the popover crashes when the props are validated (in debug mode) with "Invalid component props (TranslationButton)", `resId` being reported as a missing key of the `record` prop. The `TranslationButton` indeed requires a `resId` on the record it receives, which must be `false` when the record doesn't exist yet. The record of the popover is produced by the `Record` component (`@web/model/record`), which forwards its `resId` prop as is to the config of the standalone model. As no `resId` is given for that new record, the datapoint ends up with an `undefined` `resId`, which is considered as a missing prop by the props validation. Normalize the `resId` in the model, such that a mono record config always has a `resId`, which is `false` when the record is new, as the `FormController` and the datapoints created by the lists already do. `_getNextConfig` is the single entry point of every load, so every root datapoint is covered, whatever the caller. The next props are normalized as well in the `Record` component, otherwise each re-render of the parent would trigger a useless reload (`undefined !== false`). Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#289585
The stock app now correctly loads the information needed for the rescheduling warning popover. This prevents a page crash when users click the warning icon on delivery orders with delayed related receipts, keeping warehouse scheduling workflows usable.
Original PR description
Issue Before this Commit: ===================== Clicking on the rescheduling popover widget on the picking form leads to a page crash. Steps to Reproduce: ===================== 1. Install the `stock`…
Issue Before this Commit: ===================== Clicking on the rescheduling popover widget on the picking form leads to a page crash. Steps to Reproduce: ===================== 1. Install the `stock` module. 2. Create a storable product, then create a delivery order for it 3. Create a receipt for the same product, and `set its Scheduled Date to a date later than the delivery order's Scheduled Date`. 4. Open the Allocation Report from the receipt and assign the received quantity to the delivery order. 5. Open the delivery order and click the Danger icon next to the Scheduled Date. Observe that the page crashes with the following error: `Uncaught Promise > Invalid loop expression: "undefined" is not iterable` Cause of the Issue: ===================== The `late_elements` is not defined in `useProps` of `StockRescheculingPopoverComponent`, even though it was used by the `stock.PopoverStockRescheduling` template. As a result, the template tried to iterate over `undefined`, leading to a page crash. After this Commit: ===================== This commit defines the `late_elements` and `delay_alert_date` in useProps so that the values are correctly available in the component and the rescheduling popover renders without crashing. Forward-Port-Of: odoo/odoo#288895
Fixes an error that could stop payment validation in Point of Sale when settling a sale order for a made-to-order manufactured product. This ensures staff can complete those POS transactions reliably without interruption.
Original PR description
Step to reproduce: ------------------ - Install `pos_sale_stock` and `mrp` module. - Go to the setting enable "Replenish on Order (MTO)" - Create a storable product with the MTO route - Create a Bill…
Step to reproduce:
------------------
- Install `pos_sale_stock` and `mrp` module.
- Go to the setting enable "Replenish on Order (MTO)"
- Create a storable product with the MTO route
- Create a Bill of Materials for the product with a storable component
- Now Create Sale order for the Product and confirm it.
- Open POS Store and settel Created sale order.
- Process toward payment and try to validate it.
Issue:
------
`AssertionError: Invalid falsy real id`
Cause:
------
When an MTO product with a manufacturing Bill of Materials is added to a Sale Order and the SO is confirmed, Odoo creates two distinct sets of stock.move records that share the same stock.reference group:
1. **Delivery moves** (picking_id → stock.picking) Created by the outgoing stock rule triggered by the MTO route. These moves are assigned to a delivery picking and have a valid picking_id.
2. **Manufacturing component moves** (picking_id = False) Created by the Manufacture route's procurement rule, which spawns an mrp.production. The raw-material moves inside an MO belong to the production order, not to any stock.picking. Their picking_id field is intentionally False by design.
Both sets of moves are linked to the same stock.reference record through the stock_reference_move_rel many2many table. This means that traversing:
so_line.move_ids → delivery move(s)
.reference_ids → shared stock.reference
.move_ids → ALL moves in the group (delivery + MRP)
every move in the reference group, including MRP component moves whose picking_id is False.
- Then In PosOrder.sync_from_ui(), the code collected the IDs of all related pickings into a set for later cancellation:
https://github.com/odoo/odoo/blob/a0cdf9c33ed464b4ec8bd520e4d0523afb8dbd28/addons/pos_sale/models/pos_order.py#L111
https://github.com/odoo/odoo/blob/a0cdf9c33ed464b4ec8bd520e4d0523afb8dbd28/addons/pos_sale/models/pos_order.py#L130-L133
waiting_picking_ids.add(move.picking_id.id) # ← adds False for MRP moves
Because MRP moves pass the state filter ('confirmed') but have picking_id = False, `move.picking_id.id` evaluates to False (the empty recordset's falsy id), which was silently added to the waiting_picking_ids set.
Issue occur from this [commit](https://github.com/odoo/odoo/commit/515eb5ba0892a759dde32a9b2923d8ecc1e4bf74?debug=1), the ORM assertion in browse() rejects falsy IDs:
https://github.com/odoo/odoo/blob/a0cdf9c33ed464b4ec8bd520e4d0523afb8dbd28/addons/pos_sale/models/pos_order.py#L139
https://github.com/odoo/odoo/blob/9e02922f821a3b4e891e90bf9bd18448a08e66fa/odoo/orm/models.py#L5297
Fix:
---
Add guards in `sync_from_ui()`
*Inner filtered() guard* — add `m.picking_id` as the first condition so
that MRP component moves (picking_id = False) are never iterated, preventing
`False` from ever entering the set
---
opw-6486681
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#289890
Forward-Port-Of: odoo/odoo#284103Customers who sign in during an active live chat will no longer lose the chat window or chat button. This keeps the conversation available after login, reducing interruptions and failed handoffs during customer support interactions.
Original PR description
Before this commit, a visitor signing in during a live chat session sometimes landed on a page with neither the chat window nor the live chat button, which fails website_livechat.chatbot_continue_after_login_tour on its "Your email is validated, thank you!" step. This happens because the login moves the live chat sessions of the guest to the partner of the user, and unlinking a member tells the bus channel of that member to close the chat window of the channel. The browser that just signed in still listens on the bus channel of its guest, so that order closes the conversation the visitor is taking over. An order arriving before the page restores its chat windows changes nothing, which is why the tour fails only under load. This commit fixes the issue by unlinking the guest members with close_chat_window=False, so that nothing tells the visitor to close the session they keep. https://runbot.odoo.com/odoo/error/947173 Forward-Port-Of: odoo/odoo#289993