Summary
With the sqlite-wasm driver, an authenticated POST to the REST data API for crm_account repeatedly fails with:
COMMIT; - cannot commit - no transaction is active
returned as { "error": "COMMIT; - cannot commit - no transaction is active" } (HTTP 500). The same authenticated session creates crm_lead records successfully, and the seed loader creates accounts fine at boot — so it's specific to a subset of user-context writes, not all writes.
This looks like a transaction begin/commit pairing bug in the driver (a COMMIT issued when no BEGIN is active — double-commit or a nested-transaction mismatch).
Environment
@objectstack/driver-sqlite-wasm 7.4.1
@objectstack/runtime / cli / objectql 7.4.1
- Node v25.9.0, launched via
objectstack start with OS_DATABASE_DRIVER=sqlite-wasm
- Repro app: https://github.com/objectstack-ai/hotcrm
Observed (confirmed)
In one authenticated Console session (logged in, on /home):
| Write |
Path |
Result |
crm_account insert |
POST /api/v1/data/crm_account |
❌ COMMIT; - cannot commit - no transaction is active — 3× consecutive |
crm_lead insert |
POST /api/v1/data/crm_lead |
✅ succeeds (other sessions) |
crm_account insert (seed, system context) |
boot-time defineDataset |
✅ succeeds (Acme/Globex/Wayne exist) |
So: system-context (seed) account inserts work; user-context (REST) account inserts fail; user-context lead inserts work.
Repro
OS_DATABASE_DRIVER=sqlite-wasm objectstack start -p 4001
# register + log in via /_console
# in the authenticated browser context:
fetch('/api/v1/data/crm_account', {
method: 'POST', credentials: 'include',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'X', industry: 'technology', type: 'prospect' })
}).then(r => r.json()) // → { error: "COMMIT; - cannot commit - no transaction is active" }
Hypothesis
The failing object (crm_account) differs from the succeeding one (crm_lead) in two ways that add steps to the write transaction:
crm_account has a criteria sharing rule (AccountTeamSharingRule); crm_lead has none. Opportunity/Case also have sharing rules and are good candidates to check.
crm_account has a beforeInsert/beforeUpdate/beforeDelete protection hook.
A plausible cause is the sharing-rule (or hook) path opening/closing an inner transaction that leaves the driver's transaction stack unbalanced, so the outer COMMIT runs with no active transaction. The seed path bypasses sharing recompute (system context), which is consistent with it succeeding.
Suggested checks
- Audit
BEGIN/COMMIT/ROLLBACK pairing in driver-sqlite-wasm when a write triggers nested operations (sharing-rule recomputation, cascade writes, hook-issued sub-queries). Compare against driver-sql (better-sqlite3), which I did not see exhibit this on the same write.
- Add a regression test: authenticated insert of an object that has a criteria sharing rule, under
sqlite-wasm.
Repro caveat
I couldn't produce a fully isolated minimal repro in this pass (browser-auth flakiness + better-auth registration throttling after many test users interfered). Happy to add a LiteKernel-level repro (driver + objectql + an object with a sharing rule + authenticated insert) if useful for triage.
Possibly related
May share a root cause with the silent-trigger investigation in #1491 (both surface only under user-context writes), but filing separately since the symptom and layer (driver transaction lifecycle) are distinct.
Summary
With the
sqlite-wasmdriver, an authenticatedPOSTto the REST data API forcrm_accountrepeatedly fails with:returned as
{ "error": "COMMIT; - cannot commit - no transaction is active" }(HTTP 500). The same authenticated session createscrm_leadrecords successfully, and the seed loader creates accounts fine at boot — so it's specific to a subset of user-context writes, not all writes.This looks like a transaction begin/commit pairing bug in the driver (a
COMMITissued when noBEGINis active — double-commit or a nested-transaction mismatch).Environment
@objectstack/driver-sqlite-wasm7.4.1@objectstack/runtime/cli/objectql7.4.1objectstack startwithOS_DATABASE_DRIVER=sqlite-wasmObserved (confirmed)
In one authenticated Console session (logged in, on
/home):crm_accountinsertPOST /api/v1/data/crm_accountCOMMIT; - cannot commit - no transaction is active— 3× consecutivecrm_leadinsertPOST /api/v1/data/crm_leadcrm_accountinsert (seed, system context)defineDatasetSo: system-context (seed) account inserts work; user-context (REST) account inserts fail; user-context lead inserts work.
Repro
Hypothesis
The failing object (
crm_account) differs from the succeeding one (crm_lead) in two ways that add steps to the write transaction:crm_accounthas a criteria sharing rule (AccountTeamSharingRule);crm_leadhas none. Opportunity/Case also have sharing rules and are good candidates to check.crm_accounthas abeforeInsert/beforeUpdate/beforeDeleteprotection hook.A plausible cause is the sharing-rule (or hook) path opening/closing an inner transaction that leaves the driver's transaction stack unbalanced, so the outer
COMMITruns with no active transaction. The seed path bypasses sharing recompute (system context), which is consistent with it succeeding.Suggested checks
BEGIN/COMMIT/ROLLBACKpairing indriver-sqlite-wasmwhen a write triggers nested operations (sharing-rule recomputation, cascade writes, hook-issued sub-queries). Compare againstdriver-sql(better-sqlite3), which I did not see exhibit this on the same write.sqlite-wasm.Repro caveat
I couldn't produce a fully isolated minimal repro in this pass (browser-auth flakiness + better-auth registration throttling after many test users interfered). Happy to add a LiteKernel-level repro (driver + objectql + an object with a sharing rule + authenticated insert) if useful for triage.
Possibly related
May share a root cause with the silent-trigger investigation in #1491 (both surface only under user-context writes), but filing separately since the symptom and layer (driver transaction lifecycle) are distinct.