Kuberwastaken/claurst · error · anyhow::Error
Failed to store MCP token for
Error message
Failed to store MCP token for '{}': {} What it means
After a successful OAuth flow completes, the resulting token is persisted via oauth::store_mcp_token. If persistence fails (I/O error, storage backend unavailable), the original error is wrapped with this message naming the server. The token may still be valid in memory but was not saved, so it will not survive the session.
Solutions
- Inspect the inner error text to see the underlying storage failure
- Check that the token/config directory exists and is writable by the process
- Re-run the auth flow once the storage issue is fixed — the token is not persisted
- Free disk space / resolve file locks if the store could not be written
Defensive patterns
Strategy: try-catch
Validate before calling
let dir = token_store_dir()?;
let probe = dir.join(".write-probe");
std::fs::write(&probe, b"ok").context("token store dir not writable")?;
let _ = std::fs::remove_file(&probe); Try / catch
match oauth::store_mcp_token(&token) {
Ok(()) => {}
Err(e) => {
eprintln!("warning: token for {server} not persisted: {e}; re-auth next session");
}
} Prevention
- Ensure the config/token directory exists and is writable before starting auth
- Avoid running multiple auth flows concurrently against the same store
- Monitor free disk space on hosts running the auth flow
- On failure, re-run authentication before relying on the token later
When it happens
Trigger: run_mcp_auth_flow() finished the browser flow but store_mcp_token(&mcp_token) returned Err — disk full, auth-store file locked/unwritable, storage directory missing, or serialization failure.
Common situations: Home directory or config dir not writable (sandboxed process, read-only FS); concurrent runs of the auth flow corrupting/locking the token store; disk quota exceeded; corrupted auth store file forcing rewrite failure.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- models endpoint returned
- MCP server ' ' is configured as ' ' but missing URL
- Unknown MCP server
- MCP server ' ' has no URL configured (required for OAuth)
- Invalid JWT: expected at least 2 dot-separated segments
AI-assisted analysis of Kuberwastaken/claurst@b0637c97ec (2026-09-10).
Data as JSON: /api/errors/9dc6cb9cb020c3d4.
Report an issue: GitHub.
Appendix: source
Thrown at src-rust/crates/mcp/src/lib.rs:1281
token: &str,
expires_in: Option<u64>,
) -> anyhow::Result<()> {
let expires_at = expires_in.map(|secs| {
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap_or_default()
.as_secs()
+ secs
});
let mcp_token = oauth::McpToken {
access_token: token.to_string(),
refresh_token: None,
expires_at,
scope: None,
server_name: server_name.to_string(),
};
oauth::store_mcp_token(&mcp_token)
.map_err(|e| anyhow::anyhow!("Failed to store MCP token for '{}': {}", server_name, e))
}
/// Load the stored OAuth access token for an MCP server, if any.
///
/// Returns `None` if no token is stored or the token cannot be refreshed.
pub async fn load_token(&self, server_name: &str) -> Option<String> {
let config = self.server_configs.get(server_name)?;
let server_url = config.url.as_deref()?;
oauth::get_valid_mcp_access_token(server_name, server_url)
.await
.ok()
.flatten()
}
// -----------------------------------------------------------------------
// Notification dispatch loop
// -----------------------------------------------------------------------
View on GitHub (pinned to b0637c97ec)