clockworklabs/SpacetimeDB · error · anyhow::Error
Session token is missing in response.
Error message
Session token is missing in response.
What it means
The final step of web-login session handling: data.approved is true, meaning the user approved in the browser, but data.session_token is None. Since an approved session without a token cannot be exchanged for a SpacetimeDB token, the CLI aborts with 'Session token is missing in response.' rather than proceeding with a null credential.
Solutions
- Restart `spacetime login` — if the auth backend was mid-incident, a fresh flow usually completes
- Update the CLI to the latest version to match the current auth API contract
- If a security product/proxy strips token fields, allowlist the SpacetimeDB auth host and retry
Defensive patterns
Strategy: retry
Try / catch
for i in 1 2; do spacetime login && break; echo "token exchange incomplete — retry $i"; sleep 3; done
Prevention
- Complete the approval quickly so the session token is issued while fresh
- Ensure security software/proxies don't strip fields named like sessionToken from responses
- Report persistent occurrences with CLI version + server host — approved-but-tokenless is a server contract violation
When it happens
Trigger: Auth API returns success:true, data:{approved:true} but omits the sessionToken field (serde rename). Server-side bug or response-mangling middlebox; in the standard flow the token is always issued on approval, so this is a contract violation by the endpoint.
Common situations: Auth service version skew where approval succeeds but token issuance fails silently server-side; proxies or response filters removing fields containing the word 'token'; partially failing auth backends during incidents.
Related errors
- Response data is missing.
- Failed to request token
- Unknown error
- Failed to get token
- Login required to publish to maincloud server
AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20).
Data as JSON: /api/errors/4c2bf9693ead79d3.
Report an issue: GitHub.
Appendix: source
Thrown at crates/cli/src/subcommands/login.rs:199
impl WebLoginSessionResponse {
fn approved(self) -> anyhow::Result<Option<WebLoginSessionResponseApproved>> {
if !self.success {
return Err(anyhow::anyhow!(self
.error
.clone()
.unwrap_or("Unknown error".to_string())));
}
let data = self.data.ok_or(anyhow::anyhow!("Response data is missing."))?;
if !data.approved {
// Approved is false, no session token expected
return Ok(None);
}
let session_token = data
.session_token
.ok_or(anyhow::anyhow!("Session token is missing in response.".to_string()))?;
Ok(Some(WebLoginSessionResponseApproved {
session_token: session_token.clone(),
}))
}
}
async fn web_login(remote: &Url, open_browser: bool) -> Result<String, anyhow::Error> {
let client = reqwest::Client::new();
let response: WebLoginTokenResponse = client
.post(remote.join("/api/auth/cli/login/request-token")?)
.send()
.await?
.error_for_status()?
.json()
.await?;
if !response.success {View on GitHub (pinned to 6dee26c6ef)