Skip to content

Replace SQLite UPSERT with INSERT OR REPLACE (Lambda python3.9) - #12

Merged
mneuronico merged 1 commit into
mainfrom
fix/sqlite-upsert-lambda
Sep 30, 2026
Merged

mneuronico merged 1 commit into
mainfrom
fix/sqlite-upsert-lambda

Conversation

@mneuronico

Copy link
Copy Markdown
Owner

Problem

AWS Lambda's python3.9 runtime (the MAWS default) ships SQLite 3.7.17, which predates UPSERT (added in 3.24). In history_mode="shared", the first rotation of a shared history file writes closed_at with INSERT ... ON CONFLICT(key) DO UPDATE, which fails with near "ON": syntax error. Because the file never gets marked closed, every later message retries the rotation and fails, so the bot stops answering. Seen in production on a bot with shared history + FIFO.

The same syntax was also in clear_message_history (shared mode, reached by /clear) and clear_global_history.

Fix

Replace the three UPSERTs with INSERT OR REPLACE. history_metadata is a two-column table with key as primary key and no triggers, so the result is identical.

Tests

  • tests/test_sqlite_compat.py emulates the old SQLite parser (rejects UPSERT/RETURNING with the same error). Rotation, metadata replacement, /clear and global clear fail on main with the exact production traceback and pass with this change.
  • A static guard fails if UPSERT/RETURNING syntax appears anywhere in mas/ or maws/; on main it flags exactly the three lines fixed here.
  • Rest of the SQL in MAS was audited and is compatible with SQLite 3.7.17. Full suite passes locally (the known flaky parallel-automation test aside).

🤖 Generated with Claude Code

AWS Lambda's python3.9 runtime (the MAWS default) ships SQLite 3.7.17,
which predates UPSERT (3.24). In shared history mode the first rotation
wrote closed_at with ON CONFLICT ... DO UPDATE and failed with
'near "ON": syntax error' on every later message, so the bot stopped
answering. The same syntax was in clear_message_history and
clear_global_history.

history_metadata is a two-column table keyed by key, so INSERT OR REPLACE
is equivalent. Tests emulate the old SQLite parser and add a static guard
against UPSERT/RETURNING in mas/ and maws/.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mneuronico
mneuronico merged commit a0f3ec7 into main Sep 30, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant