Facing (ir_sequence_strict) Error at Front Desk Office after clicking on PAY NOW Button

We are using Tryton 6.0/GNU Health 4.2.0 development & Our system is Facing this (ir_sequence_strict) Error again and again (many times a day) at Front Desk Office after clicking on PAY NOW Button. When ever a sale is made, at Pay Now button pressed cause this error (ir_sequence_strict) on Every FDO Desk at same time.

After closing this error and performing same action, this error disappears and Pay Now successfully Done.

Now we are unable to track this from where it has been raised and what are the causes for this Error.
Error snaps are also attached. :pensive_face:

This is a constraint in place to avoid missing invoice numbers. So if many users are doing this multiple times a day, it can happen when one of them triggers the action while another one is waiting for it to complete.

This should be very rare, unless you have a lot of users, or if the action itself is very slow.

More recent versions try to be more intelligent on this and will retry a few times in the background, leading to some waiting for the occasional unlucky user, but no errors.

It will be interesting to have the full traceback in plain text to understand exactly where this happens.

But you can still start by increasing [database] retry.

If it is not enough, it will be necessary to analyze and see if it is not possible to use different sequences to reduce the contention.

By the way, series 6.0 is no more supported, you should consider upgrade.

Is there any situation or method through which we can trace where this error is being raised from and on what basis? For example, whether it is based on Cust_inv_numb, POS_Sale, or some other sequence. We just need a way to trace and identify the exact source or logic behind the error. Can you suggest any method for that?

The server should log as an exception such case.

Plz see…

[Wed Jun 03 17:58:06 2026] INFO:root:=====---------------------------------- returning is ret sale: False
[Wed Jun 03 17:58:06 2026] INFO:werkzeug:127.0.0.1 - - [03/Jun/2026 17:58:06] “e[37mPOST /cbr_hmis_db/ HTTP/1.1e[0m” 200 -
[Wed Jun 03 17:58:06 2026] INFO:werkzeug:127.0.0.1 - - [03/Jun/2026 17:58:06] “e[37mPOST /cbr_hmis_db/ HTTP/1.1e[0m” 200 -
[Wed Jun 03 17:58:07 2026] INFO:trytond.wsgi:<JSONRequest 354@127.0.0.1http://172.27.35.21:8000/cbr_hmis_db/’ [POST] wizard.health.proc.sale.payment.wizard.execute>
[Wed Jun 03 17:58:07 2026] INFO:werkzeug:127.0.0.1 - - [03/Jun/2026 17:58:07] “e[37mPOST /cbr_hmis_db/ HTTP/1.1e[0m” 200 -
[Wed Jun 03 17:58:07 2026] INFO:werkzeug:127.0.0.1 - - [03/Jun/2026 17:58:07] “e[37mPOST /cbr_hmis_db/ HTTP/1.1e[0m” 200 -
[Wed Jun 03 17:58:07 2026] INFO:trytond.wsgi:<JSONRequest 354@127.0.0.1http://172.27.35.21:8000/cbr_hmis_db/’ [POST] model.health.proc.confirm.pos.payment.start.fields_view_get>
[Wed Jun 03 17:58:07 2026] INFO:trytond.wsgi:<JSONRequest 56@127.0.0.1http://172.27.35.21:8000/cbr_hmis_db/’ [POST] model.gnuhealth.healthprofessional.search_read>
[Wed Jun 03 17:58:07 2026] INFO:werkzeug:127.0.0.1 - - [03/Jun/2026 17:58:07] “e[37mPOST /cbr_hmis_db/ HTTP/1.1e[0m” 200 -
[Wed Jun 03 17:58:07 2026] INFO:trytond.wsgi:<JSONRequest 354@127.0.0.1http://172.27.35.21:8000/cbr_hmis_db/’ [POST] model.health.proc.confirm.pos.payment.start.on_change>
[Wed Jun 03 17:58:07 2026] INFO:werkzeug:127.0.0.1 - - [03/Jun/2026 17:58:07] “e[37mPOST /cbr_hmis_db/ HTTP/1.1e[0m” 200 -
[Wed Jun 03 17:58:07 2026] INFO:trytond.wsgi:<JSONRequest 249@127.0.0.1http://172.27.35.21:8000/cbr_hmis_db/’ [POST] model.gnuhealth.lab.test_type.search_read>
[Wed Jun 03 17:58:07 2026] INFO:werkzeug:127.0.0.1 - - [03/Jun/2026 17:58:07] “e[37mPOST /cbr_hmis_db/ HTTP/1.1e[0m” 200 -
[Wed Jun 03 17:58:08 2026] INFO:trytond.wsgi:<JSONRequest 56@127.0.0.1http://172.27.35.21:8000/cbr_hmis_db/’ [POST] model.gnuhealth.healthprofessional.search_read>
[Wed Jun 03 17:58:08 2026] INFO:werkzeug:127.0.0.1 - - [03/Jun/2026 17:58:08] “e[37mPOST /cbr_hmis_db/ HTTP/1.1e[0m” 200 -
[Wed Jun 03 17:58:08 2026] INFO:trytond.wsgi:<JSONRequest 577@127.0.0.1http://172.27.35.21:8000/cbr_hmis_db/’ [POST] wizard.gnuhealth.request.lab_test.fast.wizard.execute>
[Wed Jun 03 17:58:08 2026] INFO:trytond.wsgi:<JSONRequest 249@127.0.0.1http://172.27.35.21:8000/cbr_hmis_db/’ [POST] model.gnuhealth.patient.lab.test.request.start.on_change_tests>
[Wed Jun 03 17:58:08 2026] INFO:werkzeug:127.0.0.1 - - [03/Jun/2026 17:58:08] “e[37mPOST /cbr_hmis_db/ HTTP/1.1e[0m” 200 -
[Wed Jun 03 17:58:08 2026] INFO:trytond.wsgi:<JSONRequest 249@127.0.0.1http://172.27.35.21:8000/cbr_hmis_db/’ [POST] model.gnuhealth.lab.test_type.read>
[Wed Jun 03 17:58:08 2026] INFO:werkzeug:127.0.0.1 - - [03/Jun/2026 17:58:08] “e[37mPOST /cbr_hmis_db/ HTTP/1.1e[0m” 200 -
[Wed Jun 03 17:58:09 2026] INFO:werkzeug:127.0.0.1 - - [03/Jun/2026 17:58:09] “e[37mPOST /cbr_hmis_db/ HTTP/1.1e[0m” 200 -
[Wed Jun 03 17:58:09 2026] INFO:root:{“success”:“false”,“results”:[{“error”:“No Any Whats APP Account Available At The Moment To Handle This Request!”}]}
[Wed Jun 03 17:58:09 2026] INFO:werkzeug:127.0.0.1 - - [03/Jun/2026 17:58:09] “e[37mPOST /cbr_hmis_db/ HTTP/1.1e[0m” 200 -
[Wed Jun 03 17:58:10 2026] INFO:trytond.wsgi:<JSONRequest 577@127.0.0.1http://172.27.35.21:8000/cbr_hmis_db/’ [POST] model.health.proc.confirm.pos.payment.start.on_change>
[Wed Jun 03 17:58:10 2026] INFO:werkzeug:127.0.0.1 - - [03/Jun/2026 17:58:10] “e[37mPOST /cbr_hmis_db/ HTTP/1.1e[0m” 200 -
[Wed Jun 03 17:58:10 2026] INFO:trytond.wsgi:<JSONRequest 56@127.0.0.1http://172.27.35.21:8000/cbr_hmis_db/’ [POST] model.anth.proc.hp_services.search_read>
[Wed Jun 03 17:58:10 2026] INFO:werkzeug:127.0.0.1 - - [03/Jun/2026 17:58:10] “e[37mPOST /cbr_hmis_db/ HTTP/1.1e[0m” 200 -
[Wed Jun 03 17:58:12 2026] INFO:trytond.wsgi:<JSONRequest 249@127.0.0.1http://172.27.35.21:8000/cbr_hmis_db/’ [POST] model.gnuhealth.lab.test_type.search_read>
[Wed Jun 03 17:58:12 2026] INFO:werkzeug:127.0.0.1 - - [03/Jun/2026 17:58:12] “e[37mPOST /cbr_hmis_db/ HTTP/1.1e[0m” 200 -
[Wed Jun 03 17:58:12 2026] INFO:trytond.wsgi:<JSONRequest 56@127.0.0.1http://172.27.35.21:8000/cbr_hmis_db/’ [POST] model.product.product.search_read>
[Wed Jun 03 17:58:12 2026] INFO:werkzeug:127.0.0.1 - - [03/Jun/2026 17:58:12] “e[37mPOST /cbr_hmis_db/ HTTP/1.1e[0m” 200 -
[Wed Jun 03 17:58:13 2026] INFO:trytond.wsgi:<JSONRequest 249@127.0.0.1http://172.27.35.21:8000/cbr_hmis_db/’ [POST] model.gnuhealth.patient.lab.test.request.start.on_change_tests>
[Wed Jun 03 17:58:13 2026] INFO:werkzeug:127.0.0.1 - - [03/Jun/2026 17:58:13] “e[37mPOST /cbr_hmis_db/ HTTP/1.1e[0m” 200 -
[Wed Jun 03 17:58:13 2026] INFO:trytond.wsgi:<JSONRequest 249@127.0.0.1http://172.27.35.21:8000/cbr_hmis_db/’ [POST] model.gnuhealth.lab.test_type.read>
[Wed Jun 03 17:58:13 2026] INFO:werkzeug:127.0.0.1 - - [03/Jun/2026 17:58:13] “e[37mPOST /cbr_hmis_db/ HTTP/1.1e[0m” 200 -
[Wed Jun 03 17:58:13 2026] INFO:trytond.wsgi:<JSONRequest 354@127.0.0.1http://172.27.35.21:8000/cbr_hmis_db/’ [POST] wizard.health.proc.sale.payment.wizard.execute>
[Wed Jun 03 17:58:14 2026] INFO:root:Pre-payment checks passed — calling super().transition_pay_()
[Wed Jun 03 17:58:14 2026] INFO:root:super().transition_pay_() returned state=end
[Wed Jun 03 17:58:15 2026] INFO:trytond.wsgi:<JSONRequest 56@127.0.0.1http://172.27.35.21:8000/cbr_hmis_db/’ [POST] wizard.gnuhealth.request.lab_test.fast.wizard.execute>
[Wed Jun 03 17:58:16 2026] INFO:root:{“success”:“false”,“results”:[{“error”:“No Any Whats APP Account Available At The Moment To Handle This Request!”}]}
[Wed Jun 03 17:58:16 2026] INFO:werkzeug:127.0.0.1 - - [03/Jun/2026 17:58:16] “e[37mPOST /cbr_hmis_db/ HTTP/1.1e[0m” 200 -
[Wed Jun 03 17:58:17 2026] INFO:trytond.wsgi:<JSONRequest 56@127.0.0.1http://172.27.35.21:8000/cbr_hmis_db/’ [POST] model.health.proc.confirm.pos.payment.start.on_change>
[Wed Jun 03 17:58:17 2026] INFO:werkzeug:127.0.0.1 - - [03/Jun/2026 17:58:17] “e[37mPOST /cbr_hmis_db/ HTTP/1.1e[0m” 200 -
[Wed Jun 03 17:58:17 2026] INFO:trytond.wsgi:<JSONRequest 56@127.0.0.1http://172.27.35.21:8000/cbr_hmis_db/’ [POST] wizard.gnuhealth.request.lab_test.fast.wizard.execute>
[Wed Jun 03 17:58:18 2026] INFO:root:Doctor 624: next OPD counter=1
[Wed Jun 03 17:58:18 2026] INFO:root:Pre-payment checks passed — calling super().transition_pay_()
[Wed Jun 03 17:58:18 2026] INFO:root:super().transition_pay_() returned state=end
[Wed Jun 03 17:58:18 2026] INFO:root:Doctor 624: next OPD counter=1
[Wed Jun 03 17:58:18 2026] INFO:root:Pre-payment checks passed — calling super().transition_pay_()
[Wed Jun 03 17:58:19 2026] INFO:root:super().transition_pay_() returned state=end
[Wed Jun 03 17:58:19 2026] INFO:root:Doctor 624: next OPD counter=1
[Wed Jun 03 17:58:19 2026] INFO:root:Pre-payment checks passed — calling super().transition_pay_()
[Wed Jun 03 17:58:19 2026] INFO:root:super().transition_pay_() returned state=end
[Wed Jun 03 17:58:20 2026] INFO:trytond.wsgi:<JSONRequest 127.0.0.1 ‘http://172.27.35.21:8000/cbr_hmis_db/lis_apis/results_lis_upload’ [POST]>
[Wed Jun 03 17:58:20 2026] INFO:root:Doctor 624: next OPD counter=1
[Wed Jun 03 17:58:20 2026] INFO:root:Pre-payment checks passed — calling super().transition_pay_()
[Wed Jun 03 17:58:20 2026] ERROR:root:Formula calculation failed for Absolute Neutrophil Count: name ‘neut’ is not defined
[Wed Jun 03 17:58:20 2026] ERROR:root:Formula calculation failed for Absolute Lymphocyte Count: name ‘lymph’ is not defined
[Wed Jun 03 17:58:20 2026] ERROR:root:Formula calculation failed for Absolute Monocyte Count: name ‘mono’ is not defined
[Wed Jun 03 17:58:20 2026] ERROR:root:Formula calculation failed for Absolute Eosinophil Count: name ‘eos’ is not defined
[Wed Jun 03 17:58:20 2026] ERROR:root:Formula calculation failed for Absolute Basophil Count: name ‘baso’ is not defined
[Wed Jun 03 17:58:20 2026] INFO:root:super().transition_pay_() returned state=end
[Wed Jun 03 17:58:20 2026] ERROR:root:Formula calculation failed for Absolute Neutrophil Count: name ‘neut’ is not defined
[Wed Jun 03 17:58:20 2026] ERROR:root:Formula calculation failed for Absolute Lymphocyte Count: name ‘lymph’ is not defined
[Wed Jun 03 17:58:20 2026] ERROR:root:Formula calculation failed for Absolute Monocyte Count: name ‘mono’ is not defined
[Wed Jun 03 17:58:20 2026] ERROR:root:Formula calculation failed for Absolute Eosinophil Count: name ‘eos’ is not defined
[Wed Jun 03 17:58:20 2026] ERROR:root:Formula calculation failed for Absolute Neutrophil Count: name ‘neut’ is not defined
[Wed Jun 03 17:58:20 2026] ERROR:root:Formula calculation failed for Absolute Lymphocyte Count: name ‘lymph’ is not defined
[Wed Jun 03 17:58:20 2026] ERROR:root:Formula calculation failed for Absolute Monocyte Count: name ‘mono’ is not defined
[Wed Jun 03 17:58:20 2026] ERROR:root:Formula calculation failed for Absolute Neutrophil Count: name ‘neut’ is not defined
[Wed Jun 03 17:58:20 2026] ERROR:root:Formula calculation failed for Absolute Monocyte Count: name ‘mono’ is not defined
[Wed Jun 03 17:58:20 2026] INFO:root:Doctor 624: next OPD counter=1
[Wed Jun 03 17:58:20 2026] ERROR:root:Formula calculation failed for Absolute Neutrophil Count: name ‘neut’ is not defined
[Wed Jun 03 17:58:20 2026] INFO:root:Pre-payment checks passed — calling super().transition_pay_()
[Wed Jun 03 17:58:21 2026] ERROR:root:Formula calculation failed for Absolute Neutrophil Count: name ‘neut’ is not defined
[Wed Jun 03 17:58:21 2026] ERROR:root:Formula calculation failed for Absolute Neutrophil Count: name ‘neut’ is not defined
[Wed Jun 03 17:58:21 2026] INFO:root:super().transition_pay_() returned state=end
[Wed Jun 03 17:58:21 2026] ERROR:root:Formula calculation failed for Absolute Neutrophil Count: name ‘neut’ is not defined
[Wed Jun 03 17:58:21 2026] ERROR:root:Formula calculation failed for Absolute Neutrophil Count: name ‘neut’ is not defined
[Wed Jun 03 17:58:21 2026] ERROR:root:Formula calculation failed for Absolute Neutrophil Count: name ‘neut’ is not defined
[Wed Jun 03 17:58:21 2026] INFO:root:Doctor 624: next OPD counter=1
[Wed Jun 03 17:58:21 2026] INFO:root:Pre-payment checks passed — calling super().transition_pay_()
[Wed Jun 03 17:58:21 2026] ERROR:root:Formula calculation failed for Absolute Neutrophil Count: name ‘neut’ is not defined
[Wed Jun 03 17:58:21 2026] ERROR:root:Formula calculation failed for Absolute Neutrophil Count: name ‘neut’ is not defined
[Wed Jun 03 17:58:21 2026] INFO:root:super().transition_pay_() returned state=end
[Wed Jun 03 17:58:21 2026] ERROR:root:Formula calculation failed for Absolute Neutrophil Count: name ‘neut’ is not defined
[Wed Jun 03 17:58:22 2026] INFO:werkzeug:127.0.0.1 - - [03/Jun/2026 17:58:22] “e[37mPOST /cbr_hmis_db/lis_apis/results_lis_upload HTTP/1.1e[0m” 200 -
[Wed Jun 03 17:58:22 2026] ERROR:trytond.protocols.dispatcher:<class ‘trytond.modules.health_proc.wizard.wizard_request_lab_test_fast.RequestLabTestFastWizard’>.execute(*(3538933, {‘confirm_payment’: {‘account_paymenttype’: None, ‘cashamount’: Decimal(‘550.00’), ‘device’: 34, ‘net_amount’: Decimal(‘550.00’), ‘otheramount’: Decimal(‘0.00’), ‘sale’: 1148670, ‘total_amount’: Decimal(‘550.00’), ‘user’: 56, ‘welfare’: None, ‘welfare_discount’: Decimal(‘0’), ‘id’: -78}}, ‘pay_now’, {‘client’: ‘7fa8f300-945b-43d1-abdd-a4d0de7bbb30’, ‘lab_department’: , ‘locations’: [1], ‘health_center’: 1, ‘health_center.rec_name’: ‘Raazi Islamabad’, ‘shops’: [1], ‘shop’: 1, ‘shop.rec_name’: 'AKHF Main ‘, ‘warehouse’: 32, ‘warehouse.rec_name’: ‘Raazi Warehouse’, ‘company_filter’: ‘one’, ‘company’: 1, ‘company.rec_name’: ‘Raazi Islamabad’, ‘language’: ‘en’, ‘language_direction’: ‘ltr’, ‘groups’: [66, 55, 68, 64, 58, 59, 8, 97, 61, 6, 62, 38, 39], ‘locale’: {‘date’: ‘%m/%d/%Y’, ‘grouping’: [3, 3, 0], ‘decimal_point’: ‘.’, ‘thousands_sep’: ‘,’}, ‘active_id’: 432, ‘active_ids’: None, ‘active_model’: ‘ir.ui.menu’, ‘action_id’: 514}), **{}) from m.nadeem@127.0.0.1/cbr_hmis_db/
Traceback (most recent call last):
File “/home/gnuhealth/gnuhealth/tryton/server/trytond-6.0.28/trytond/protocols/dispatcher.py”, line 180, in _dispatch
result = rpc.result(meth(*c_args, **c_kwargs))
^^^^^^^^^^^^^^^^^^^^^^^^^
File “/home/gnuhealth/gnuhealth/tryton/server/trytond-6.0.28/trytond/wizard/wizard.py”, line 313, in execute
return wizard._execute(state_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/home/gnuhealth/gnuhealth/tryton/server/trytond-6.0.28/trytond/wizard/wizard.py”, line 344, in _execute
result = self.execute(transition())
^^^^^^^^^^^^
File “/home/gnuhealth/gnuhealth/tryton/server/trytond-6.0.28/trytond/modules/health_proc/wizard/wizard_request_lab_test_fast.py”, line 333, in transition_pay_now
SalePaymentWizard.execute(session_id, {‘start’: fields}, 'pay
’)
File “/home/gnuhealth/gnuhealth/tryton/server/trytond-6.0.28/trytond/wizard/wizard.py”, line 313, in execute
return wizard._execute(state_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/home/gnuhealth/gnuhealth/tryton/server/trytond-6.0.28/trytond/wizard/wizard.py”, line 344, in _execute
result = self.execute(transition())
^^^^^^^^^^^^
File “/home/gnuhealth/gnuhealth/tryton/server/trytond-6.0.28/trytond/modules/sale_pos/sale.py”, line 397, in transition_pay

Sale.print_ticket([sale])
File “/home/gnuhealth/gnuhealth/tryton/server/trytond-6.0.28/trytond/model/modelview.py”, line 789, in wrapper
value = func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File “/home/gnuhealth/gnuhealth/tryton/server/trytond-6.0.28/trytond/model/modelview.py”, line 775, in wrapper
return func(cls, records, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/home/gnuhealth/gnuhealth/tryton/server/trytond-6.0.28/trytond/modules/sale_pos/sale.py”, line 160, in print_ticket
sale.ticket_number = config.pos_sequence.get()
^^^^^^^^^^^^^^^^^^^^^^^^^
File “/home/gnuhealth/gnuhealth/tryton/server/trytond-6.0.28/trytond/ir/sequence.py”, line 394, in get
return super().get(_lock=True)
^^^^^^^^^^^^^^^^^^^^^^^
File “/home/gnuhealth/gnuhealth/tryton/server/trytond-6.0.28/trytond/ir/sequence.py”, line 378, in get
cursor.execute(*query)
File “/home/gnuhealth/gnuhealth/tryton/server/trytond-6.0.28/trytond/backend/postgresql/database.py”, line 74, in execute
cursor.execute(self, sql, args)
psycopg2.errors.LockNotAvailable: could not obtain lock on row in relation “ir_sequence_strict”

Your traceback already pins it down. The sequence raising the lock is not the customer invoice sequence nor the POS sale sequence — it is the POS ticket sequence (pos_sequence), which sale_pos assigns to sale.ticket_number inside print_ticket:

sale.ticket_number = config.pos_sequence.get()
  → ir/sequence.py:394  get() → super().get(_lock=True)
  → ir/sequence.py:378  cursor.execute(*query)
  → psycopg2.errors.LockNotAvailable: could not obtain lock on row in relation "ir_sequence_strict"

So, to answer your question directly: it is pos_sequence.

Why it happens. pos_sequence is an ir.sequence.strict, not a plain ir.sequence. The two behave very differently:

  • A plain ir.sequence uses a native PostgreSQL sequence. It is non-transactional and never rolls back: it can leave gaps, but it never blocks and never duplicates.

  • An ir.sequence.strict keeps its counter in a table row and locks that row with SELECT ... FOR UPDATE NOWAIT (the _lock=True in the trace). The number is only consumed if the transaction commits, which is what guarantees gap-less numbering. Because the lock is NOWAIT, a concurrent transaction that finds the row already locked fails immediately instead of waiting — that is exactly the LockNotAvailable (PostgreSQL 55P03) you are getting.

The row stays locked from the get() call until the whole transaction commits. When two payments hit the same pos_sequence at the same time, the second one cannot take the row and raises. Your log confirms the concurrency: around 17:58:18–22 there are many transition_pay_ calls within one or two seconds — several front desks paying simultaneously, all competing for the same row in ir_sequence_strict. trytond retries the whole transaction ([database] retry, default 5), but under enough concurrency the retry budget runs out and the error reaches the user. On the retry after closing the dialog the contention is gone, so it succeeds — which matches what you describe.

What you can do, from least to most invasive:

  1. Increase [database] retry, as already suggested above. This mitigates but does not remove the cause.

  2. Shorten the time the lock is held. Commit as soon as possible after print_ticket, and move slow side effects out of the payment transaction into the async queue — in your log the WhatsApp call and the LIS upload are good candidates. Each retry replays the entire transaction, so a heavy transaction is penalized twice: more contention and more expensive retries. The custom code overriding transition_pay_ (the “Pre-payment checks passed…” / “Doctor 624: next OPD counter=1” lines) is adding work to that transaction.

  3. Reduce contention by splitting the sequence: one pos_sequence per device or per shop instead of a single global one. Two desks on different sequences do not compete for the same row. This is what was meant above by using different sequences.

  4. Question whether the ticket number needs to be strict at all. Is the POS ticket a fiscal document that legally requires gap-less numbering in your country? If gaps in the ticket number are acceptable (the fiscal invoice number is a separate sequence), switching it to a plain ir.sequence removes the locking entirely. If it must be gap-less, keep it strict. This is a legal decision, not a technical one.

  5. Upgrade. As noted, 6.0 is no longer supported, and newer series retry in the background, so the occasional unlucky user waits instead of seeing an error.

Two unrelated things in your log, so you don’t conflate them with this issue:

  • Formula calculation failed ... name 'neut' is not defined (and lymph, mono, eos, baso): a separate bug in your CBC differential formula evaluation — those variable names are undefined in the evaluation scope. Nothing to do with the sequence lock.

  • No Any Whats APP Account Available...: your WhatsApp integration failing. Separate, and only relevant here because it adds latency to the request flow (point 2).