sipeed/picoclaw · error
get device ID via whoami: %w
Error message
get device ID via whoami: %w
What it means
Thrown by MatrixChannel.initCrypto when the logged-in client has no DeviceID and the homeserver lookup POST /_matrix/client/v3/account/whoami fails (pkg/channels/matrix/matrix.go:375). The crypto store is keyed by device ID, so it must be resolved before cryptoHelper.Init. The homeserver rejects whoami with 401 M_UNKNOWN_TOKEN for an invalid/expired access token; network failures, DNS errors, and a canceled startup context also surface here. The DB is closed on this path.
Source
Thrown at pkg/channels/matrix/matrix.go:375
}
// Wrap with dbutil for dialect support
wrappedDB, err := dbutil.NewWithDB(db, sqliteDriver)
if err != nil {
_ = db.Close()
return fmt.Errorf("wrap database: %w", err)
}
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.DefinitionListsView on GitHub (pinned to 49183d7e8d)
Solutions
- Verify the token out-of-band: curl -H 'Authorization: Bearer <token>' https://homeserver/_matrix/client/v3/account/whoami — 401 means regenerate the token and update config
- Check homeserver reachability and the configured server URL; fix DNS/proxy issues
- Re-login to obtain a fresh token (and persist device_id to skip the whoami path next start)
- Retry startup if it was a transient network failure
Example fix
# diagnose
curl -s -H "Authorization: Bearer $MATRIX_TOKEN" \
https://matrix.example.org/_matrix/client/v3/account/whoami
# {"errcode":"M_UNKNOWN_TOKEN","error":"Invalid token"} -> token expired: re-login and update config Defensive patterns
Strategy: retry
Validate before calling
// cheap token liveness check before starting the channel
func tokenAlive(ctx context.Context, hs, token string) error {
req, _ := http.NewRequestWithContext(ctx, http.MethodGet, hs+"/_matrix/client/v3/account/whoami", nil)
req.Header.Set("Authorization", "Bearer "+token)
resp, err := http.DefaultClient.Do(req)
if err != nil { return err }
defer resp.Body.Close()
if resp.StatusCode == http.StatusUnauthorized {
return errors.New("access token invalid/expired: re-login required")
}
return nil
} Try / catch
for attempt := 0; attempt < 5; attempt++ {
err := matrixCh.Start(ctx)
if err == nil { break }
var httpErr mautrix.HTTPError
if errors.As(err, &httpErr) && httpErr.RespError != nil && httpErr.RespError.Errcode == "M_UNKNOWN_TOKEN" {
refreshAccessToken() // permanent: rotate token, do not retry
continue
}
time.Sleep(backoff(attempt)) // transient network: backoff and retry
} Prevention
- Persist device_id with the token so whoami is only needed on first boot
- Monitor token expiry and rotate proactively for long-running bots
- Distinguish 401 M_UNKNOWN_TOKEN (permanent) from network errors (transient) before retrying
When it happens
Trigger: Logging in with an access token that was revoked (password changed, sessions invalidated, token rotated by another bot instance); homeserver unreachable (wrong URL, DNS failure, firewall); reverse proxy returning 5xx on the client API; startup context canceled before device discovery; using a token whose device was deleted server-side.
Common situations: Long-lived bot deployments where the shared access token expired or was invalidated by the user; homeserver migration or restart during bot startup; typo in the homeserver URL; load balancer health-check gaps. DeviceID is typically empty when authenticating by token without a stored device_id from a previous run.
Related errors
- wrap database: %w
- deltachat configure (check email/password/server): %w
- execute %s: %w
- create crypto helper: %w
- init crypto helper: %w
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/b45be312bb600eb7.
Report an issue: GitHub.