{"record":{"id":"888c4d3ab865b9ce","repo":"chenhg5/cc-connect","slug":"create-crypto-helper-w","errorCode":null,"errorMessage":"create crypto helper: %w","messagePattern":"create crypto helper: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/matrix/e2ee.go","lineNumber":194,"sourceCode":"\t}\n\tcryptoDir := filepath.Join(homeDir, \".cc-connect\")\n\tif err := os.MkdirAll(cryptoDir, 0o700); err != nil {\n\t\treturn nil, fmt.Errorf(\"create data dir: %w\", err)\n\t}\n\tdbPath := filepath.Join(cryptoDir, fmt.Sprintf(\"matrix-crypto-%s.db\", client.DeviceID))\n\n\t// Derive a stable pickle key from the access token\n\th := sha256.Sum256([]byte(p.accessToken))\n\tpickleKey := make([]byte, 32)\n\tcopy(pickleKey, h[:])\n\n\treturn p.tryInitCrypto(ctx, client, pickleKey, dbPath, false)\n}\n\nfunc (p *Platform) tryInitCrypto(ctx context.Context, client *mautrix.Client, pickleKey []byte, dbPath string, isRetry bool) (*cryptohelper.CryptoHelper, error) {\n\tch, err := cryptohelper.NewCryptoHelper(client, pickleKey, dbPath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"create crypto helper: %w\", err)\n\t}\n\tch.DBAccountID = client.UserID.String()\n\n\tif err := ch.Init(ctx); err != nil {\n\t\tif !isRetry && strings.Contains(err.Error(), \"not marked as shared\") {\n\t\t\tslog.Warn(\"matrix: stale device keys on server, force-uploading new keys\")\n\t\t\tfunc() {\n\t\t\t\tdefer func() { recover() }()\n\t\t\t\tif mach := ch.Machine(); mach != nil {\n\t\t\t\t\tif shareErr := mach.ShareKeys(ctx, -1); shareErr != nil {\n\t\t\t\t\t\tslog.Error(\"matrix: failed to force-share keys\", \"error\", shareErr)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}()\n\t\t\tch.Close()\n\t\t\tclient.StateStore = nil\n\t\t\tclient.Store = mautrix.NewMemorySyncStore()\n\t\t\treturn p.tryInitCrypto(ctx, client, pickleKey, dbPath, true)","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/matrix/e2ee.go#L176-L212","documentation":"This error wraps any failure from cryptohelper.NewCryptoHelper() when the Matrix platform adapter initializes its end-to-end-encryption helper. NewCryptoHelper builds a SQL crypto store (pickle key, device identity, olm/megolm machinery) at dbPath; if constructing the store, parsing the user ID, or opening the database fails, the error is wrapped with context and returned to initCrypto, aborting E2EE setup.","triggerScenarios":"tryInitCrypto calls cryptohelper.NewCryptoHelper(client, pickleKey, dbPath) and it returns err — e.g. the crypto store database at dbPath cannot be opened/created, the SQL driver is unavailable, the pickle key is invalid/empty in a way the store rejects, or the underlying mautrix client state is inconsistent.","commonSituations":"The data directory for the crypto DB does not exist or is not writable (read-only filesystem, wrong permissions, container volume not mounted); the configured DB path uses an unsupported sqlstore URI; the pickle key was generated with a broken RNG or reused/corrupted state from a previous run.","solutions":["Ensure the directory containing dbPath exists and is writable by the process (mkdir -p and chown/chmod).","Verify the dbPath scheme matches an available store backend (e.g. sqlite3 driver compiled in); add the driver import if missing.","Delete a corrupted crypto store DB and restart to force fresh key upload (the code already handles 'not marked as shared' retries, but corruption may need manual cleanup).","Regenerate the pickle key and restart the platform so a fresh helper is created.","Check startup logs for the underlying wrapped error to identify the store-level cause."],"exampleFix":"// before\nch, err := cryptohelper.NewCryptoHelper(client, pickleKey, \"/var/lib/cc-connect/crypto.db\")\n// after\nif err := os.MkdirAll(\"/var/lib/cc-connect\", 0o755); err != nil {\n    return nil, fmt.Errorf(\"prepare crypto db dir: %w\", err)\n}\nch, err := cryptohelper.NewCryptoHelper(client, pickleKey, \"/var/lib/cc-connect/crypto.db\")","handlingStrategy":"try-catch","validationCode":"// Go: before starting the platform, ensure the crypto DB path is usable\nif err := os.MkdirAll(filepath.Dir(dbPath), 0o755); err != nil {\n    return fmt.Errorf(\"crypto db dir not creatable: %w\", err)\n}\nif f, err := os.OpenFile(dbPath+\".probe\", os.O_CREATE|os.O_WRONLY, 0o600); err != nil {\n    return fmt.Errorf(\"crypto db path not writable: %w\", err)\n} else { f.Close(); os.Remove(dbPath + \".probe\") }","typeGuard":null,"tryCatchPattern":"plat, err := matrix.New(opts)\nif err != nil {\n    var ctxErr error\n    if errors.As(err, &ctxErr) && strings.Contains(err.Error(), \"create crypto helper\") {\n        slog.Error(\"E2EE store setup failed — check crypto db path/permissions\", \"cause\", errors.Unwrap(err))\n    }\n    return err\n}","preventionTips":["Pre-create and permission the data directory holding the crypto DB in deployment scripts.","Use an absolute, stable dbPath so restarts reuse the same store.","Import your SQL driver (e.g. _ \"modernc.org/sqlite\") before constructing the helper.","Monitor startup logs for 'create crypto helper' during config changes."],"tags":["matrix","e2ee","database","crypto-store"],"backgroundTag":"database-query-failed","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}