sipeed/picoclaw · error
init crypto helper: %w
Error message
init crypto helper: %w
What it means
Thrown by MatrixChannel.initCrypto when cryptoHelper.Init fails (pkg/channels/matrix/matrix.go:382). Init loads or creates the Olm account in the SQLite store, runs crypto DB migrations, uploads device identity keys to the homeserver (POST /_matrix/client/v3/keys/upload), and starts key-share request loops. So the error mixes local store failures (unreadable pickle because the passphrase changed, failed schema migration) and server-side failures (keys/upload 4xx/5xx, network). cryptoHelper.Close() runs first, then startup aborts.
Source
Thrown at pkg/channels/matrix/matrix.go:382
}
cryptoHelper, err := cryptohelper.NewCryptoHelper(c.client, []byte(c.config.CryptoPassphrase), wrappedDB)
if err != nil {
return fmt.Errorf("create crypto helper: %w", err)
}
if c.client.DeviceID == "" {
resp, whoamiErr := c.client.Whoami(ctx)
if whoamiErr != nil {
_ = db.Close()
return fmt.Errorf("get device ID via whoami: %w", whoamiErr)
}
c.client.DeviceID = resp.DeviceID
}
if err = cryptoHelper.Init(ctx); err != nil {
cryptoHelper.Close()
return fmt.Errorf("init crypto helper: %w", err)
}
c.client.Crypto = cryptoHelper
c.cryptoHelper = cryptoHelper
logger.InfoC("matrix", "Crypto helper initialized successfully")
return nil
}
func markdownToHTML(md string) string {
extensions := (parser.CommonExtensions | parser.NoEmptyLineBeforeBlock) &^ parser.DefinitionLists
p := parser.NewWithExtensions(extensions)
renderer := mdhtml.NewRenderer(mdhtml.RendererOptions{Flags: mdhtml.UseXHTML})
return strings.TrimSpace(string(markdown.ToHTML([]byte(md), p, renderer)))
}
func (c *MatrixChannel) Send(ctx context.Context, msg bus.OutboundMessage) ([]string, error) {
if !c.IsRunning() {View on GitHub (pinned to 49183d7e8d)
Solutions
- Read the wrapped error first — 'pickle'/'account' points to a passphrase mismatch, 'migration'/'no such table' to schema version skew, HTTP status codes to homeserver problems
- If the passphrase changed or migration is impossible, archive/delete the crypto DB directory and restart — the bot creates fresh device keys (users must re-verify the device; old encrypted history stays undecryptable for it)
- Keep maunium.net/go/mautrix and this bot's versions in lockstep when carrying a crypto DB forward
- For homeserver-side failures, verify /keys/upload works (network, auth token still valid) and retry startup
Example fix
# before: passphrase changed but old crypto state kept crypto_passphrase: "new-secret" # Init fails: cannot unpickle account # after: rotate state together with the passphrase crypto_passphrase: "new-secret" mv /var/lib/bot/crypto /var/lib/bot/crypto.bak # bot re-registers device keys on next start
Defensive patterns
Strategy: try-catch
Try / catch
if err := matrixCh.Start(ctx); err != nil {
msg := err.Error()
switch {
case strings.Contains(msg, "unpickle"), strings.Contains(msg, "pickle key"): // passphrase changed vs stored account
archiveCryptoDb() // move dir aside; device re-registers, users re-verify
return matrixCh.Start(ctx)
case strings.Contains(msg, "migration"), strings.Contains(msg, "no such table"): // version skew
log.Fatal("crypto db schema incompatible; upgrade path required: ", err)
default: // network / keys-upload: safe to retry with backoff
return backoff.Retry(func() error { return matrixCh.Start(ctx) }, policy)
}
} Prevention
- Rotate CryptoPassphrase and crypto DB together — never one without the other
- Back up the crypto DB before every bot upgrade that bumps mautrix
- Test startup against a copy of the production crypto DB in staging first
- Alert on 'init crypto helper' failures: they disable all E2EE for the session
When it happens
Trigger: An existing crypto DB whose Olm account was pickled with a different CryptoPassphrase than the one now configured; crypto DB schema written by an older/newer mautrix version so migration fails; homeserver rejecting /keys/upload (frozen account, misconfigured rate limits, auth mid-expiry); network outage during key upload; SQLite errors on the crypto DB (permissions, corruption).
Common situations: Rotating the crypto passphrase without deleting the old crypto DB; upgrading mautrix/bot versions with a stale crypto DB; homeserver temporarily down right when the bot starts; moving the crypto DB file between hosts with different SQLite versions.
Related errors
- execute %s: %w
- create crypto helper: %w
- wrap database: %w
- get device ID via whoami: %w
- decrypt matrix media: %w
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/b390c3236d46a430.
Report an issue: GitHub.