pgref.dev/sqlite/errors/SQLITE_MISUSE
SQLITE_MISUSEERRORTier 1 — Safe✅ HIGH confidence

bad parameter or other API misuse

Category: API MisuseVersions: All SQLite versions

What this means

SQLITE_MISUSE (result code 21) is returned when the SQLite C library detects that it is being called incorrectly — for example, using a finalised database connection, executing a statement after it has been finalised, or calling sqlite3_step() on a statement that was not properly reset. In Python, misuse scenarios are rarer because the sqlite3 module wraps the C API, but they can occur with third-party extensions.

Why it happens

  1. 1Calling methods on a closed database connection
  2. 2Using a connection or cursor after it has been garbage-collected in C extensions
  3. 3Attempting to finalise an already-finalised statement (C API)
  4. 4Concurrent access to a non-thread-safe connection without proper locking

How to reproduce

A connection is closed and then a query is attempted on it.

trigger — this will ERROR
import sqlite3
conn = sqlite3.connect(':memory:')
conn.execute('CREATE TABLE t (x INTEGER)')
conn.close()
conn.execute('SELECT * FROM t')  # triggers ProgrammingError (wraps SQLITE_MISUSE)
sqlite3.ProgrammingError: Cannot operate on a closed database.

Fix 1: Use context managers to manage connection lifetime

Always — to ensure connections are properly closed and not used after close.

fix
import sqlite3

with sqlite3.connect(':memory:') as conn:
    conn.execute('CREATE TABLE t (x INTEGER)')
    conn.execute('INSERT INTO t VALUES (1)')
    rows = conn.execute('SELECT * FROM t').fetchall()
# conn is closed heredo not use it outside the with block

Why this works

The context manager protocol guarantees the connection is committed (or rolled back) and closed when the with block exits, making it impossible to accidentally use a closed connection.

What not to do

Share a single connection object across multiple threads without locking

Why it's wrong: SQLite connections are not thread-safe by default. Concurrent use without locking is API misuse and can produce SQLITE_MISUSE or data corruption.

Version notes

All versionsPython's sqlite3 module raises ProgrammingError (not OperationalError) for most SQLITE_MISUSE conditions since they represent programming errors rather than runtime failures.

Sources

📚 Official docs: https://www.sqlite.org/rescode.html#misuse

🔧 Source ref: sqlite3.h — SQLITE_MISUSE = 21

📖 Further reading: SQLite threading mode documentation

Confidence assessment

✅ HIGH confidence

Stable. The threading safety requirements are well-documented.

See also

📄 Reference pages

SQLite threadingconnection lifecycle
⚙️ This error reference was generated with AI assistance and reviewed for accuracy. Examples are provided to illustrate common scenarios and may not cover every case. Always test fixes in a development environment before applying to production. Spotted an error? Suggest a correction →