What it means
A connection has at most one transaction open at a time, and SQLite’s BEGIN … COMMIT
transactions don’t nest. Running BEGIN while one is open fails with SQLITE_ERROR (code 1) and
cannot start a transaction within a transaction. The open transaction carries on unaffected.
Two related messages mean the opposite mismatch, COMMIT or ROLLBACK with nothing open:
cannot commit - no transaction is activecannot rollback - no transaction is active
And VACUUM refuses to run inside a transaction: cannot VACUUM from within a transaction.
In each case, your code’s idea of whether a transaction is open differs from the connection’s.
Common causes
- Your driver already began one. Python’s
sqlite3module, by default, opens a transaction by itself before the firstINSERT,UPDATE,DELETEorREPLACE; an explicitBEGINafter that fails. Withautocommit=False(Python 3.12 and later), a transaction is always open. - Nested code. A function that runs
BEGINis called from code that already began a transaction. - A transaction left open. An error path skipped
COMMITorROLLBACK, and the nextBEGINon that connection, perhaps from a pool, fails. - The transaction already ended. The driver committed for you, an earlier
COMMITran twice, or SQLite rolled back because of an error: anINSERT OR ROLLBACK(orON CONFLICT ROLLBACK) conflict always does, andSQLITE_FULL,SQLITE_IOERR,SQLITE_INTERRUPTandSQLITE_NOMEMerrors can. TheCOMMITthen has nothing to commit. - VACUUM in a transaction: a migration tool that wraps every step in a transaction, or Python code that wrote something and hasn’t committed yet.
How to fix it
Ask the connection
In C, sqlite3_get_autocommit(db) returns non-zero when no transaction is open. In Python,
connection.in_transaction is True while one is. Check it where the error occurs rather than
guessing.
Let the driver handle it, or take it over completely
With Python’s sqlite3, either don’t run BEGIN at all and let the module manage transactions
(with connection: commits on success and rolls back on an exception), or turn its handling off and
issue every BEGIN and COMMIT yourself:
connection = sqlite3.connect("app.db", autocommit=True) # Python 3.12+; isolation_level=None before
connection.execute("BEGIN IMMEDIATE")
# …
connection.execute("COMMIT")
Mixing the two is what produces this error. Other drivers and ORMs have the same choice; check whether yours begins transactions for you.
Use savepoints for inner transactions
Savepoints nest, inside a transaction or on their own:
BEGIN;
SAVEPOINT import_batch;
INSERT INTO t VALUES (2);
RELEASE import_batch; -- or ROLLBACK TO import_batch to undo only this part
COMMIT;
A helper that might be called inside a transaction should use SAVEPOINT and RELEASE instead of
BEGIN and COMMIT.
Always finish what you begin
Put ROLLBACK in the error path (try/finally, defer), so a failure doesn’t leave the
connection mid-transaction for the next caller.
After “no transaction is active”, check what was saved
If an error came first, SQLite may have rolled back the whole transaction, so earlier statements are
gone too. Redo the work rather than assuming it’s committed. After SQLITE_FULL or SQLITE_IOERR,
issuing ROLLBACK yourself is safe: it fails harmlessly if SQLite already rolled back.
Run VACUUM on its own
Commit first, then run VACUUM outside any transaction. In Python, call connection.commit()
before connection.execute("VACUUM"), or use a connection with autocommit=True.
Reproduce it
macOS /usr/bin/sqlite3, SQLite 3.51.0:
sqlite3 tx.db "BEGIN; INSERT INTO t VALUES (1); BEGIN;"
Error: stepping, cannot start a transaction within a transaction
The shell adds “Error: stepping,”; SQLite’s message is
cannot start a transaction within a transaction. Run as a script, the first transaction carried
on after the failed BEGIN: another insert and a COMMIT saved both rows. With no transaction
open, COMMIT, ROLLBACK and END gave:
Error: stepping, cannot commit - no transaction is active
Error: stepping, cannot rollback - no transaction is active
Error: stepping, cannot commit - no transaction is active
A transaction ended by a conflict: BEGIN, an insert, then an INSERT OR ROLLBACK that broke a
unique constraint, then COMMIT:
Runtime error near line 3: UNIQUE constraint failed: u.x (19)
Runtime error near line 4: cannot commit - no transaction is active
The first insert was gone. With a plain INSERT in place of INSERT OR ROLLBACK, the same
conflict left the transaction open, and COMMIT saved the first insert. VACUUM after BEGIN:
Runtime error near line 2: cannot VACUUM from within a transaction
Python 3.14’s sqlite3 module (SQLite 3.53.4), default settings: after
connection.execute("INSERT …"), in_transaction was True, and connection.execute("BEGIN")
raised sqlite3.OperationalError: cannot start a transaction within a transaction. VACUUM at the
same point raised cannot VACUUM from within a transaction. On a connection opened with
autocommit=False, the first BEGIN failed the same way.
In Inlet
Grid edits are staged until you commit (⌘S) and then go in as one transaction. In the query
editor, with manual commit, finish each transaction with COMMIT or ROLLBACK before you begin
another.