Isolate d1 import sqlite3 runs from user config#1288
Merged
Conversation
The sqlite3 shell loads ~/.sqliterc even for one-shot invocations, so settings like .headers on or .mode column change the output format and break row count parsing during import verification. Invoke sqlite3 with -batch -noheader -init /dev/null so output is always plain list mode. Also harden the surrounding parsing: replace Sscanf with strict strconv.ParseInt so garbage output fails loudly instead of parsing partially, include the offending output and stderr in errors, stop mixing stderr into parsed query output, and quote SQL identifiers properly instead of using Go's %q. Co-authored-by: Cursor <cursoragent@cursor.com>
nholden
approved these changes
Jul 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A user hit this during a D1 import:
The cause is that the sqlite3 shell loads
~/.sqliterceven for one-shot invocations. If that file turns on headers or column mode, the output ofSELECT COUNT(*)is no longer a bare integer and the import verification fails. Reproduced locally: with.headers onin~/.sqliterc,sqlite3 db "SELECT COUNT(*) FROM t"printsCOUNT(*)before the number, which is exactly what broke the parse. Setting$HOMEdoes not help because sqlite3 finds the rc file through the passwd database.Changes
-batch -noheader -init /dev/null, so output is always plain list mode regardless of the user's.sqliterc.fmt.Sscanf("%d")with strictstrconv.ParseInt. Sscanf accepts trailing garbage ("3 rows"parses as 3) and its "expected integer" error carries no context, which is why this bug was hard to diagnose from the report. Parse errors now quote the actual output.runSQLiteQueryno longer parsesCombinedOutput. sqlite3 can exit 0 while printing warnings to stderr (WAL recovery, lock warnings), and those bytes were being mixed into output we split and compare. Stdout is parsed, stderr is reported only on failure."doubled) instead of Go's%q, which produces invalid SQL for names containing quotes or backslashes.Testing
.sqliterccontaining.headers onand.mode column, then confirmed the hermetic flags produce clean output with the same rc file in place.go test ./internal/import/d1/passes,go vetandgofmtclean.