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

  1. 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
  2. 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)
  3. Keep maunium.net/go/mautrix and this bot's versions in lockstep when carrying a crypto DB forward
  4. 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

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


AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15). Data as JSON: /api/errors/b390c3236d46a430. Report an issue: GitHub.