Repository navigation
Description
Summary
The V1 → V2 data migration ("V1 migration") fails on every server startup with SQLiteError: near ",": syntax error when the legacy databases contain single quotes (apostrophes) in message/part JSON payloads. The migration interpolates JSON values directly into SQL statements without escaping, so any apostrophe in a message breaks the string literal and the parser dies at the next comma.
Environment
- opencode version: 0.0.0-next-17229 (also reproduced on 0.0.0-next-17227)
- OS: Linux 7.1.7-arch1-1 (x64)
- Terminal: ghostty (TERM=xterm-ghostty)
- Shell: zsh
- Install/channel: next
- Active plugins: @mellena1/opencode-auto-mode@0.1.2
Reproduction
- Have a V1 install with message/part data containing apostrophes (e.g. tool output or user prompts with
'), plus a previous V2 (opencode-next.db) database whosesession_message.datacontains apostrophes. - Run
opencode2(server startup runs the V1 migration againstopencode.dbin place). - Migration fails every startup; the
migration.v1-v2kv entry stays at{"phase":"sessions"}and never advances.
Log (every startup):
level=ERROR message="V1 migration failed" cause="Cause([Die(SQLiteError: near \",\": syntax error)])" role=server
Relevant data found in the legacy databases:
- old V2 db
session_message: 72 of 109 rows contain'indata - V1
message: 768 of 8757 rows contain'indata - V1
part: 8805 of 40252 rows contain'indata
Expected Behavior
The V1 migration should import legacy sessions/messages regardless of content, e.g. by using parameterized statements or escaping string literals (' → '').
Actual Behavior
The migration builds INSERT statements via raw SQL string interpolation. From the installed bundle, the copy-from-previous-V2-db step runs:
INSERT INTO session_message (id, session_id, type, seq, time_created, time_updated, data)
VALUES (... ${k.data} ...)and the session conversion step runs:
INSERT INTO session_message (id, session_id, type, seq, time_created, time_updated, data)
VALUES (... ${JSON.stringify(L.data)} ...)Both interpolate unescaped JSON. An apostrophe in the payload terminates the string literal early and SQLite reports near ",": syntax error at the following comma. The transaction rolls back (including the phase cursor write), so the migration retries and fails on every startup.
Additional Context
- Updating from 0.0.0-next-17227 to 0.0.0-next-17229 did not fix it.
- Removing the old V2 db would not fix it either: the V1 message/part data itself contains apostrophes and would hit the same path.
- Workaround used to unblock: set the kv entry
migration.v1-v2to{"phase":"completed"}inopencode.db(skips the migration; legacy data remains untouched in the db). This is not a fix — the import is skipped entirely and the phase is sticky, so a fixed build should reset/clear this key when re-running. - Server log lines before the failure: schema migrations 20260804233008_loose_psylocke, 20260805200742_import_legacy_credentials, 20260808023530_workspace_domain, 20260811161259_execution_claim_attempts all complete; only the V1 data migration fails.
Activity
github-actions commentedon Aug 11, 2026
This issue might be a duplicate of (or related to) existing issues. Please check:
SQLiteError: near ",": syntax errorand the same stuck{"phase":"sessions"}state. The root cause there isundefinedvalues producing empty SQL expressions in the same string-interpolated INSERT statements — the same underlying pattern as the apostrophe escaping problem described here. Both are symptoms of the same raw SQL interpolation approach in the V1 migration code.opencode-agent commentedon Aug 12, 2026
Fixed by #41877, which now writes migrated session messages through the typed Drizzle insert builder with JSON payloads bound as SQL parameters. Regression coverage includes apostrophes in both legacy V1 data and previous-V2 message data.