SQLITE_SCHEMA
SQLiteERRORCommonSchemaHIGH confidence

database schema has changed

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
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

expected output

sqlite3.OperationalError: no such table: t

Fix

Re-prepare the statement after schema changes

WHEN When caching prepared statements across potential schema migrations.

Re-prepare the statement after schema changes
import sqlite3
conn = sqlite3.connect('demo.db')

def safe_execute(conn, sql, params=()):
    try:
        return conn.execute(sql, params)
    except sqlite3.OperationalError:
        # Schema changed — re-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

Prepared statement handles are connection-local and not serialisable. Caching them externally is meaningless.

Version notes
All versions

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

Content generated with AI assistance and reviewed for accuracy. Found an error? hello@errcodes.dev

← All SQLite errors