jdx/mise · error

{details}

Error message

{details}

What it means

Catch-all branch of poll_access_token: GitHub returned an unrecognized device-flow error code, so mise bails with the server-provided error_description if present, otherwise the raw error code string. The message content is entirely determined by GitHub's response, e.g. 'grant requires SSO authorization' or a client_id problem.

Source

Thrown at src/github/oauth.rs:371

                debug!("transient error polling GitHub OAuth token: {err:#}");
                continue;
            }
        };

        match response.error.as_deref() {
            None => return Ok(response),
            Some("authorization_pending") => continue,
            Some("slow_down") => {
                interval += 5;
                continue;
            }
            Some("expired_token") => bail!("GitHub device authorization expired"),
            Some("access_denied") => bail!("GitHub device authorization was denied"),
            Some(error) => {
                let details = response
                    .error_description
                    .unwrap_or_else(|| error.to_string());
                bail!("{details}");
            }
        }
    }
}

async fn refresh_token(cached: &CachedToken) -> Result<Option<CachedToken>> {
    let Some(refresh_token) = cached.refresh_token.as_deref() else {
        return Ok(None);
    };
    if cached
        .refresh_expires_at
        .is_some_and(|exp| exp <= chrono::Utc::now())
    {
        return Ok(None);
    }

    let settings = Settings::get();
    let url = format!(

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Read the actual message (the GitHub error_description) — it names the root cause (e.g. incorrect_client_id).
  2. Check settings.github.oauth_client_id: it must be a valid GitHub OAuth app client id; fix or clear the setting.
  3. If the org requires SSO, authorize the OAuth app for SAML SSO in the org's developer settings.
  4. Retry the flow with `mise token github --oauth`; if GitHub reports a transient error it may succeed on retry.

Example fix

// before (config.toml)
[github]
oauth_client_id = ""
// error: incorrect_client_id

// after
[github]
oauth_client_id = "Ov23liXXXXXXXXXXXXXX"
Defensive patterns

Strategy: try-catch

Validate before calling

let cid = &config.settings.github.oauth_client_id;
if cid.trim().is_empty() {
    eprintln!("settings.github.oauth_client_id is unset/invalid; fix before OAuth");
}

Type guard

fn has_valid_client_id(s: &Settings) -> bool {
    !s.github.oauth_client_id.trim().is_empty()
}

Try / catch

match token_async(req).await {
    Err(e) => {
        // message is GitHub's error_description; surface it to the user verbatim
        eprintln!("GitHub device flow failed: {e}");
    }
    Ok(t) => use_token(&t),
}

Prevention

When it happens

Trigger: poll_access_token matches Some(error) where error is none of authorization_pending/slow_down/expired_token/access_denied — e.g. "unsupported_grant_type", "incorrect_client_id", SSO-required errors — and bails with the response's error_description (or the code itself if absent).

Common situations: Misconfigured settings.github.oauth_client_id (empty, wrong app); organization requires SAML SSO authorization for the OAuth app; GitHub API contract changes introducing a new error code.

Related errors


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/f5decced2419dec9. Report an issue: GitHub.