pgref.dev/sqlite/errors/SQLITE_SCHEMA
SQLITE_SCHEMAERRORTier 1 — Safe✅ HIGH confidence

database schema has changed

Category: SchemaVersions: All SQLite versions

What this means

SQLITE_SCHEMA (result code 17) is returned when a prepared statement is re-executed but the database schema has changed since the statement was first prepared. SQLite automatically re-prepares and retries the statement once, so in practice applications rarely see this error unless a prepared statement is explicitly cached across schema migrations.

Why it happens

  1. 1A table was dropped, renamed, or had columns added/removed between prepare and execute
  2. 2An application caches prepared statements and another connection or process alters the schema
  3. 3A schema-modifying PRAGMA (e.g. user_version) triggered an internal schema version increment

How to reproduce

A prepared statement object is retained and reused after another connection drops the table it references.

trigger — this will ERROR
import sqlite3

conn1 = sqlite3.connect('demo.db')
conn2 = sqlite3.connect('demo.db')
conn1.execute('CREATE TABLE t (x INTEGER)')
conn1.commit()

stmt = conn2.execute('SELECT x FROM t')  # prepared

conn1.execute('DROP TABLE t')
conn1.commit()

# Re-executing stmt now triggers SQLITE_SCHEMA (auto-retried once)
# If retry also fails, sqlite3.OperationalError is raised
sqlite3.OperationalError: no such table: t

Fix 1: Re-prepare the statement after schema changes

When caching prepared statements across potential schema migrations.

fix
import sqlite3
conn = sqlite3.connect('demo.db')

def safe_execute(conn, sql, params=()):
    try:
        return conn.execute(sql, params)
    except sqlite3.OperationalError:
        # Schema changedre-prepare and retry once
        return conn.execute(sql, params)

Why this works

SQLite already attempts one automatic re-prepare. If the retry also fails with SQLITE_SCHEMA the schema change made the statement permanently invalid, and the application needs to rebuild its query against the new schema.

What not to do

Cache prepared statement handles across application restarts in a persistent store

Why it's wrong: Prepared statement handles are connection-local and not serialisable. Caching them externally is meaningless.

Version notes

All versionsSQLite automatically retries a statement that fails with SQLITE_SCHEMA once. Only if the second attempt also fails is the error propagated to the caller.

Sources

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

🔧 Source ref: sqlite3.h — SQLITE_SCHEMA = 17

📖 Further reading: SQLite prepared statements lifecycle

Confidence assessment

✅ HIGH confidence

Stable. The auto-retry behaviour is documented in the C API reference and consistent across all versions.

See also

📄 Reference pages

SQLite prepared statementsschema versioning
⚙️ 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 →