{"record":{"id":"d4c298949b0fa37c","repo":"sipeed/picoclaw","slug":"wrap-database-w","errorCode":null,"errorMessage":"wrap database: %w","messagePattern":"wrap database: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/channels/matrix/matrix.go","lineNumber":363,"sourceCode":"\t// This is equivalent to the \"sqlite3-fk-wal\" dialect used by cryptohelper\n\tpragmaStmts := []string{\n\t\t\"PRAGMA foreign_keys = ON\",\n\t\t\"PRAGMA journal_mode = WAL\",\n\t\t\"PRAGMA synchronous = NORMAL\",\n\t\t\"PRAGMA busy_timeout = 5000\",\n\t}\n\tfor _, pragma := range pragmaStmts {\n\t\tif _, err = db.ExecContext(ctx, pragma); err != nil {\n\t\t\t_ = db.Close()\n\t\t\treturn fmt.Errorf(\"execute %s: %w\", pragma, err)\n\t\t}\n\t}\n\n\t// Wrap with dbutil for dialect support\n\twrappedDB, err := dbutil.NewWithDB(db, sqliteDriver)\n\tif err != nil {\n\t\t_ = db.Close()\n\t\treturn fmt.Errorf(\"wrap database: %w\", err)\n\t}\n\n\tcryptoHelper, err := cryptohelper.NewCryptoHelper(c.client, []byte(c.config.CryptoPassphrase), wrappedDB)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"create crypto helper: %w\", err)\n\t}\n\n\tif c.client.DeviceID == \"\" {\n\t\tresp, whoamiErr := c.client.Whoami(ctx)\n\t\tif whoamiErr != nil {\n\t\t\t_ = db.Close()\n\t\t\treturn fmt.Errorf(\"get device ID via whoami: %w\", whoamiErr)\n\t\t}\n\t\tc.client.DeviceID = resp.DeviceID\n\t}\n\n\tif err = cryptoHelper.Init(ctx); err != nil {\n\t\tcryptoHelper.Close()","sourceCodeStart":345,"sourceCodeEnd":381,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/pkg/channels/matrix/matrix.go#L345-L381","documentation":"Thrown by MatrixChannel.initCrypto when dbutil.NewWithDB fails to wrap the raw *sql.DB with mautrix's dbutil layer (pkg/channels/matrix/matrix.go:363). dbutil provides the SQL dialect (the sqliteDriver constant \"sqlite\" doubles as the dialect label) that the mautrix crypto store uses for its queries and migrations. Failure means the dialect could not be resolved for the driver name or the *sql.DB handle is unusable, and the DB is closed before returning.","triggerScenarios":"Calling dbutil.NewWithDB with a driver/dialect name the linked mautrix version does not recognize; passing a nil or already-closed *sql.DB; version skew between maunium.net/go/mautrix, its dbutil package, and modernc.org/sqlite after a partial dependency upgrade; the *sql.DB opened with a connection string the driver rejects at first use.","commonSituations":"Upgrading mautrix (go.mod pins maunium.net/go/mautrix v0.27.0) without regenerating go.sum (go mod tidy); swapping the SQLite driver (mattn/go-sqlite3 vs modernc.org/sqlite) so the registered driver name no longer matches the dialect string; vendoring mismatches in downstream forks of this bot.","solutions":["Run 'go mod tidy' so maunium.net/go/mautrix, its dbutil, and modernc.org/sqlite versions are consistent","Confirm sqliteDriver still matches the driver name registered by modernc.org/sqlite (\"sqlite\") in the linked version","Inspect the wrapped error with '%w' unwrapping (errors.As/errors.Unwrap) — dbutil reports the concrete rejection reason","If it persists, test the raw handle first with db.PingContext(ctx) before wrapping to isolate driver-level failure from dialect resolution"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// no caller-side pre-check exists; classify at startup and fail fast with the wrapped cause\nif err := matrixCh.Start(ctx); err != nil {\n\tif strings.Contains(err.Error(), \"wrap database\") {\n\t\tlog.Fatalf(\"dbutil rejected the sqlite dialect; check mautrix/modernc versions are in lockstep: %v\", err)\n\t}\n\treturn err\n}","preventionTips":["Pin maunium.net/go/mautrix and modernc.org/sqlite together and run 'go mod tidy' after upgrades","Add a smoke test that boots the Matrix channel with a temp crypto dir in CI to catch dialect regressions","Never construct the *sql.DB with a different driver name than the dialect you pass on"],"tags":["go","matrix","mautrix","dbutil","sqlite","initialization"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}