hive-claude: recognize OAuth-refresh give-up as an auth failure
This commit is contained in:
parent
7908332168
commit
d580270263
1 changed files with 21 additions and 4 deletions
|
|
@ -32,13 +32,17 @@ const RATE_LIMIT_MARKERS: [&str; 5] = [
|
|||
"Request rate limit exceeded",
|
||||
];
|
||||
|
||||
/// Substrings indicating the API rejected the request as unauthenticated (401)
|
||||
/// — an expired/revoked OAuth session. Sourced from claude-code's `api_retry`
|
||||
/// JSON events and its human-readable give-up line.
|
||||
const AUTH_FAIL_MARKERS: [&str; 3] = [
|
||||
/// Substrings indicating the session is unauthenticated — either the API
|
||||
/// rejected the request (401, an expired/revoked OAuth session) or the CLI
|
||||
/// gave up refreshing its local OAuth token before ever making a request.
|
||||
/// Sourced from claude-code's `api_retry` JSON events and its human-readable
|
||||
/// give-up lines (two distinct give-up messages: a rejected request, and a
|
||||
/// failed local token refresh).
|
||||
const AUTH_FAIL_MARKERS: [&str; 4] = [
|
||||
"\"error\":\"authentication_failed\"",
|
||||
"\"error_status\":401",
|
||||
"Failed to authenticate. API Error: 401",
|
||||
"Failed to authenticate: OAuth session expired and could not be refreshed",
|
||||
];
|
||||
|
||||
/// Substrings indicating `--resume` could not resolve its target: no session
|
||||
|
|
@ -314,6 +318,19 @@ mod tests {
|
|||
assert!(matches!(s.soft_error(), Some(Error::PromptTooLong)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn oauth_refresh_failure_trips_auth_failed() {
|
||||
// A local OAuth token-refresh failure never reaches an API request —
|
||||
// no `error_status`/401 anywhere — so it needs its own marker rather
|
||||
// than riding the request-rejected 401 text. Observed in the wild as
|
||||
// a turn that failed with a bare non-zero exit and no recognized
|
||||
// sentinel: the harness never transitioned to needs-login because
|
||||
// this exact give-up line wasn't a marker yet.
|
||||
let s = Sentinels::default();
|
||||
s.scan_cli_line("Failed to authenticate: OAuth session expired and could not be refreshed");
|
||||
assert!(matches!(s.soft_error(), Some(Error::AuthFailed)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rate_limit_still_only_on_error_event() {
|
||||
// A non-error control event mentioning the marker must not trip it.
|
||||
|
|
|
|||
Loading…
Reference in a new issue