Skip to content

sqlite-wasm: authenticated record insert fails with "COMMIT; - cannot commit - no transaction is active" #1494

Description

@xuyushun441-sys

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 active3× 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:

  1. crm_account has a criteria sharing rule (AccountTeamSharingRule); crm_lead has none. Opportunity/Case also have sharing rules and are good candidates to check.
  2. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions