nikivdev/code · error
device code invalid. Run `f auth` again.
Error message
device code invalid. Run `f auth` again.
What it means
In `login` (src/auth.rs:101), the OAuth device-flow poll loop asks the auth server for the device-code status; when the server replies with status "invalid" the CLI bails with this message. It means the device code or user code the server received was rejected — typically it was already consumed, revoked, or mistyped. The remedy is to restart `f auth` to get a fresh code.
Source
Thrown at src/auth.rs:101
bail!("device auth poll failed: HTTP {}", poll_response.status());
}
let poll: DevicePollResponse = poll_response
.json()
.context("failed to parse device auth poll response")?;
match poll.status.as_str() {
"approved" => {
let token = poll
.token
.ok_or_else(|| anyhow!("device auth approved without token"))?;
env::save_ai_auth_token(token, Some(api_url.clone()))?;
println!("✓ Auth complete. You're ready to use Flow AI.");
return Ok(());
}
"pending" => continue,
"expired" => bail!("device code expired. Run `f auth` again."),
"invalid" => bail!("device code invalid. Run `f auth` again."),
other => bail!("unexpected auth status: {}", other),
}
}
bail!("device code expired. Run `f auth` again.")
}
fn open_in_browser(url: &str) {
#[cfg(target_os = "macos")]
{
let _ = std::process::Command::new("open").arg(url).status();
}
#[cfg(target_os = "linux")]
{
let _ = std::process::Command::new("xdg-open").arg(url).status();
}
View on GitHub (pinned to a747e741ae)
Solutions
- Run `f auth` again to get a fresh device code
- Complete browser authorization promptly instead of leaving the prompt idle
- Avoid running two `f auth` sessions concurrently
- Check the auth server URL configured for Flow AI is current
Example fix
// before
bail!("device code invalid. Run `f auth` again.");
// after
// automatic re-request of a fresh device code instead of failing:
// let (code, url) = start_device_flow(...)?; continue;
bail!("device code invalid. Run `f auth` again."); // unchanged: manual restart is the intended UX Defensive patterns
Strategy: try-catch
Try / catch
// Rust caller
match f_auth_login() {
Err(e) if e.to_string().contains("device code invalid") => {
eprintln!("Code rejected — restarting device flow...");
f_auth_login()?; // retry once with a fresh code
}
other => other?,
} Prevention
- Complete browser approval as soon as the code is shown
- Never run two `f auth` sessions at once
- Keep the CLI and auth server versions in sync
When it happens
Trigger: Calling `f auth`, the poll endpoint returns status "invalid" — e.g. the device code expired and was reaped, the code was already redeemed by a prior login, or the server invalidated the session mid-poll.
Common situations: User leaves the auth prompt open too long, runs `f auth` twice in parallel and one redeems the code, or the auth server rotates/invalidates codes after a version change or clock drift.
Related errors
- Token cannot be empty
- You don't own this project.
- `gh auth token` failed; run `gh auth login`
- Missing profile: {}
- Could not find agent file for '{}'
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/afe2031d67c209aa.
Report an issue: GitHub.