fix(setup): stop telling him the recovery key is wrong when the token is dead #141

Merged
jlxq0 merged 1 commit from setup-401-message into main 2026-08-28 02:35:03 +00:00
Owner

He was shown this, and re-entered a correct key twice, at an airport an hour before a flight:

Couldn't import the cross-signing keys: the server returned an error: [401 / M_UNKNOWN_TOKEN] Token is not active. Double-check the recovery key you pasted…

M_UNKNOWN_TOKEN cannot be caused by a wrong recovery key. The key is used client-side against Secret Storage and never reaches the homeserver as a token. The handler attributed every failure to the last thing typed, which is a check that cannot observe its subject and fails in the direction that costs the user time and tells them nothing.

What it says now

The 401 is classified as an expired session, with a 401 status rather than a 400. Everything else says plainly that this page cannot tell which of two causes it is, quotes the server's own words, and suggests checking the key as the cheaper of the two without asserting that it is the cause. A confident wrong attribution sends someone to fix a thing that is not broken.

Which token died, which decides the wording

Not the browser session's. recover deliberately reuses the cached matrix-sdk client, which holds the bearer from the MCP client's tool calls rather than /setup's own OAuth token, because routing its own token in panics matrix-sdk 0.17 with AlreadyInitializedError. So his browser session was probably fine and the MCP bearer had expired, which is why the message offers one tool call before a re-sign-in.

The cause, recorded rather than fixed here

Both are larger than a message and are in AGENTS.md:

  • expires_in is parsed from the token response and used nowhere, so nothing tracks the lifetime MAS gave the token.
  • The setup path has no equivalent of react_to_auth_expiry, which is how the MCP path notices this exact condition, evicts and rebuilds the client.

Mutations

The classifier disabled, and the lowercasing removed so only the shouty form matches. Each reddens the two classification tests, and the unclassified control stays green because it must pass either way.

Not in this repository

The consent screen reading Continue to 00000000000000000MATR1XMCP? with (no client_uri provided) is MAS configuration, not ours. This server uses a pre-registered client id from MATRIX_MCP_INTROSPECTION_CLIENT_ID and does no dynamic registration: there is no client_name, client_uri or redirect_uris anywhere in the tree. client_name and client_uri belong in MAS's own client registry.

Gates: fmt, clippy -D warnings, 301 passed; 0 failed, audit clean, deny ok.

He was shown this, and re-entered a correct key twice, at an airport an hour before a flight: > Couldn't import the cross-signing keys: the server returned an error: [401 / M_UNKNOWN_TOKEN] Token is not active. Double-check the recovery key you pasted… **`M_UNKNOWN_TOKEN` cannot be caused by a wrong recovery key.** The key is used client-side against Secret Storage and never reaches the homeserver as a token. The handler attributed **every** failure to the last thing typed, which is a check that cannot observe its subject and fails in the direction that costs the user time and tells them nothing. ## What it says now The 401 is classified as an expired session, with a 401 status rather than a 400. Everything else says plainly that this page cannot tell which of two causes it is, quotes the server's own words, and suggests checking the key as the cheaper of the two **without asserting that it is the cause**. A confident wrong attribution sends someone to fix a thing that is not broken. ## Which token died, which decides the wording **Not the browser session's.** `recover` deliberately reuses the cached matrix-sdk client, which holds the bearer from the MCP client's tool calls rather than `/setup`'s own OAuth token, because routing its own token in panics matrix-sdk 0.17 with `AlreadyInitializedError`. So his browser session was probably fine and the MCP bearer had expired, which is why the message offers **one tool call** before a re-sign-in. ## The cause, recorded rather than fixed here Both are larger than a message and are in `AGENTS.md`: - **`expires_in` is parsed from the token response and used nowhere**, so nothing tracks the lifetime MAS gave the token. - **The setup path has no equivalent of `react_to_auth_expiry`**, which is how the MCP path notices this exact condition, evicts and rebuilds the client. ## Mutations The classifier disabled, and the lowercasing removed so only the shouty form matches. Each reddens the two classification tests, and the unclassified control stays green because it must pass either way. ## Not in this repository The consent screen reading `Continue to 00000000000000000MATR1XMCP?` with `(no client_uri provided)` is **MAS configuration**, not ours. This server uses a pre-registered client id from `MATRIX_MCP_INTROSPECTION_CLIENT_ID` and does no dynamic registration: there is no `client_name`, `client_uri` or `redirect_uris` anywhere in the tree. `client_name` and `client_uri` belong in MAS's own client registry. Gates: fmt, clippy `-D warnings`, `301 passed; 0 failed`, audit clean, deny ok.
fix(setup): stop telling him the recovery key is wrong when the token is dead
All checks were successful
CI / cargo (pull_request) Successful in 1m37s
CI / docker (pull_request) Has been skipped
7a98e22bf6
He was shown "Couldn't import the cross-signing keys: the server returned an
error: [401 / M_UNKNOWN_TOKEN] Token is not active. Double-check the recovery
key you pasted" and re-entered a correct key twice, at an airport, an hour
before a flight.

M_UNKNOWN_TOKEN cannot be caused by a wrong recovery key. The key is used
client-side against Secret Storage and never reaches the homeserver as a token.
The handler attributed every failure to the last thing typed, which is a check
that cannot observe its subject and fails in the direction that costs the user
time and tells them nothing.

The 401 is now classified as an expired session with a 401 status rather than a
400, and everything else says plainly that this page cannot tell which of two
causes it is, quotes the server's own words, and suggests checking the key as
the cheaper of the two without asserting that it is the cause. A confident
wrong attribution sends someone to fix a thing that is not broken, which is the
defect being repaired rather than a lesser version of it.

The token that died is not the browser session's, which decides the wording.
recover deliberately reuses the cached matrix-sdk client, holding the bearer
from the MCP client's tool calls rather than setup's own OAuth token, because
routing its own token in panics matrix-sdk 0.17 with AlreadyInitializedError.
So the browser session was probably fine and the MCP bearer had expired, which
is why the message offers one tool call before a re-sign-in.

Two things that made it possible are recorded in AGENTS.md rather than fixed
here, because both are larger than a message: expires_in is parsed from the
token response and used nowhere, so nothing tracks the lifetime it was given,
and the setup path has no equivalent of react_to_auth_expiry, which is how the
MCP path notices this exact condition and rebuilds the client.

Mutations: the classifier disabled, and the lowercasing removed so only the
shouty form matches. Each reddens the two classification tests, and the
unclassified control stays green because it must pass either way.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FEgtox6vnEkYPv9PrCCoYG
jlxq0 merged commit bd9c708081 into main 2026-08-28 02:35:03 +00:00
jlxq0 deleted branch setup-401-message 2026-08-28 02:35:04 +00:00
Sign in to join this conversation.
No description provided.