warpdotdev/warp · error · anyhow::Error
Unexpected non-terminal OAuth status returned
Error message
Unexpected non-terminal OAuth status returned
What it means
Defensive invariant violation in the OAuth poll handler: poll_oauth_until_terminal is contractually supposed to loop until a terminal status, but it returned Ok with Pending or InProgress. The match arm's comment says 'Should not be returned by poll_oauth_until_terminal'. Reaching this error indicates a bug or behavioral change in the poll helper (or the server returning an unexpected status ordering), not a user mistake.
Source
Thrown at app/src/ai/agent_sdk/environment.rs:667
Some(Err(anyhow::anyhow!(
"GitHub authorization failed. Please try again."
))),
);
}
Ok(OauthConnectTxStatus::Expired) => {
ctx.terminate_app(
warpui::platform::TerminationMode::ForceTerminate,
Some(Err(anyhow::anyhow!(
"GitHub authorization expired. Please try again."
))),
);
}
Ok(OauthConnectTxStatus::Pending)
| Ok(OauthConnectTxStatus::InProgress) => {
// Should not be returned by poll_oauth_until_terminal.
ctx.terminate_app(
warpui::platform::TerminationMode::ForceTerminate,
Some(Err(anyhow::anyhow!(
"Unexpected non-terminal OAuth status returned"
))),
);
}
Err(err) => {
ctx.terminate_app(
warpui::platform::TerminationMode::ForceTerminate,
Some(Err(anyhow::anyhow!(
"Error polling OAuth status: {err}"
))),
);
}
}
},
);
}
(Some(auth_url), None) => {
// Legacy flow: no txId, print URL and exit.View on GitHub (pinned to e72fd7aacb)
Solutions
- Re-run the command — if transient, the next poll cycle usually completes
- Update the Warp client; the poll helper and server contract may be aligned in a newer build
- If you develop on this repo, fix poll_oauth_until_terminal so non-terminal statuses cannot be returned (keep polling instead)
- Report it with logs — this arm exists precisely to surface contract violations
Example fix
// before (oauth_flow.rs concept: returning early on any Ok status)
let status = client.get_tx_status(tx).await?;
Ok(status)
// after (loop until terminal)
loop {
let status = client.get_tx_status(tx).await?;
match status {
OauthConnectTxStatus::Pending | OauthConnectTxStatus::InProgress => continue,
terminal => return Ok(terminal),
}
} Defensive patterns
Strategy: retry
Try / catch
Ok(OauthConnectTxStatus::Pending | OauthConnectTxStatus::InProgress) => {
// contract violation from poll_oauth_until_terminal: log loudly, retry once,
// and report upstream if reproducible
} Prevention
- Keep the client updated — poll-helper fixes ship with newer builds
- If you fork/patch oauth_flow.rs, guarantee the poll loop only returns terminal statuses
- Capture logs when this fires; it indicates a code/server contract bug, not user error
- Re-run the command once before assuming a persistent defect
When it happens
Trigger: A change to poll_oauth_until_terminal (app/src/ai/agent_sdk/oauth_flow.rs) that lets non-terminal statuses escape; a server status response that the client maps to Pending/InProgress on the final poll iteration; refactoring that broke the loop's terminal-status guarantee.
Common situations: Client/server version mismatch after a server adds a new status value; recent code changes to the oauth_flow helper; race where the poll future completes on a non-terminal snapshot.
Related errors
- Error polling OAuth status: {err}
- Unexpected non-terminal OAuth status returned
- Exceeded maximum number of authorization attempts ({}). Plea
- GitHub authorization failed. Please try again.
- GitHub authorization expired. Please try again.
AI-assisted analysis of warpdotdev/warp@e72fd7aacb (2026-08-16).
Data as JSON: /api/errors/3c6e162d47eddfdf.
Report an issue: GitHub.