{"record":{"id":"7cbbdcc986452d0e","repo":"sipeed/picoclaw","slug":"open-whatsapp-store-w","errorCode":null,"errorMessage":"open whatsapp store: %w","messagePattern":"open whatsapp store: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"pkg/channels/whatsapp_native/whatsapp_native.go","lineNumber":105,"sourceCode":"\n\t// Reset lifecycle state from any previous Stop() so a restarted channel\n\t// behaves correctly.  Use reconnectMu to be consistent with eventHandler\n\t// and Stop() which coordinate under the same lock.\n\tc.reconnectMu.Lock()\n\tc.stopping.Store(false)\n\tc.reconnecting = false\n\tc.reconnectMu.Unlock()\n\n\tif err := os.MkdirAll(c.storePath, 0o700); err != nil {\n\t\treturn fmt.Errorf(\"create session store dir: %w\", err)\n\t}\n\n\tdbPath := filepath.Join(c.storePath, whatsappDBName)\n\tconnStr := \"file:\" + dbPath + \"?_foreign_keys=on\"\n\n\tdb, err := sql.Open(sqliteDriver, connStr)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"open whatsapp store: %w\", err)\n\t}\n\tdb.SetMaxOpenConns(1)\n\tdb.SetMaxIdleConns(1)\n\tif _, err = db.ExecContext(ctx, \"PRAGMA foreign_keys = ON\"); err != nil {\n\t\t_ = db.Close()\n\t\treturn fmt.Errorf(\"enable foreign keys: %w\", err)\n\t}\n\n\twaLogger := waLog.Stdout(\"WhatsApp\", \"WARN\", true)\n\tcontainer := sqlstore.NewWithDB(db, sqliteDriver, waLogger)\n\tif err = container.Upgrade(ctx); err != nil {\n\t\t_ = db.Close()\n\t\treturn fmt.Errorf(\"open whatsapp store: %w\", err)\n\t}\n\n\tdeviceStore, err := container.GetFirstDevice(ctx)\n\tif err != nil {\n\t\t_ = container.Close()","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/sipeed/picoclaw/blob/49183d7e8daed0dba89ddbb6fcb60089401d9680/pkg/channels/whatsapp_native/whatsapp_native.go#L87-L123","documentation":"Returned by WhatsAppNativeChannel.Start when sql.Open(sqliteDriver, connStr) fails for the session database 'file:<storePath>/store.db?_foreign_keys=on'. Unlike most sql drivers, open errors here mean the driver name is not registered or the DSN is rejected immediately - sql.Open itself does not touch the file. The %w preserves the database/sql error.","triggerScenarios":"Start(ctx) builds the DSN from storePath and calls sql.Open; failure occurs when the sqlite driver (CGO or pure-Go, depending on build tags) was not linked into the binary, or the DSN is malformed for the registered driver (e.g. unsupported '_foreign_keys' query parameter).","commonSituations":"Building with a driver variant that registers a different driver name (e.g. 'sqlite3' vs 'sqlite'); CGO disabled causing the CGO sqlite driver to be excluded; a build-tag mismatch between the driver import and whatsapp_native code; storePath containing characters the DSN parser rejects.","solutions":["Rebuild with the same build tags used for the sqlite driver import (whatsapp_native tag set) so the driver registers.","Confirm CGO settings match the chosen sqlite driver (CGO_ENABLED=1 for mattn/go-sqlite3, or use the pure-Go driver).","Print/inspect the effective storePath to rule out DSN-breaking characters.","Check sqliteDriver constant in the package matches the driver name registered by the imported library."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Verify the sqlite driver is linked into this build before Start:\nvar found bool\nfor _, d := range sql.Drivers() {\n    if d == \"sqlite\" { found = true }\n}\nif !found {\n    return errors.New(\"sqlite driver not compiled in; rebuild with the required build tags\")\n}","typeGuard":null,"tryCatchPattern":"if err := ch.Start(ctx); err != nil {\n    if strings.Contains(err.Error(), \"open whatsapp store\") {\n        // distinguish sql.Open failure (driver/DSN) from later upgrade failure via unwrap chain\n    }\n}","preventionTips":["Build with a consistent set of build tags so driver import and whatsapp_native code ship together.","Pin CGO_ENABLED explicitly in build scripts when using a CGO sqlite driver.","Add a startup self-check listing sql.Drivers() in debug logs."],"tags":["whatsapp","sqlite","driver","build-tags","startup"],"backgroundTag":null,"analyzedSha":"49183d7e8daed0dba89ddbb6fcb60089401d9680","analyzedAt":"2026-08-15T21:55:41.315Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}