chatboxai/chatbox · warning · Error

Device flow timed out

Error message

Device flow timed out

What it means

Thrown when the device-flow polling loop in waitForToken() reaches its 10-minute hard deadline (Date.now() + 10*60*1000) without ever receiving an access_token and without GitHub returning a terminal error. It is a guard against the user simply never completing authorization. The finally block clears pendingDeviceCode, so the flow must be restarted from scratch.

Solutions

  1. Catch this specific timeout and restart via startDeviceFlow() to issue a fresh device_code and user_code.
  2. Surface a clear UI message ('Login timed out — click to try again') rather than a generic error.
  3. Consider bumping the deadline if GitHub's documented device-code lifetime exceeds 10 minutes.

Example fix

// before
const creds = await provider.waitForToken(signal)

// after
try {
  const creds = await provider.waitForToken(signal)
  return creds
} catch (e) {
  if (/timed out/i.test(String(e))) {
    const restarted = await provider.startDeviceFlow()
    throw new ReauthRequiredError(restarted)
  }
  throw e
}
Defensive patterns

Strategy: retry

Type guard

function isDeviceFlowTimeout(e: unknown): boolean {
  return e instanceof Error && /Device flow timed out/i.test(e.message)
}

Try / catch

try {
  return await provider.waitForToken(signal)
} catch (e) {
  if (isDeviceFlowTimeout(e)) {
  // restart with a fresh device code + user code
  const fresh = await provider.startDeviceFlow()
  throw new ReauthRequiredError(fresh)
  }
  throw e
}

Prevention

When it happens

Trigger: User opened the verification URL but never entered the code or never approved; user is on a slow connection and the approval round-trip exceeded 10 minutes; the device_code lifetime is longer than this deadline and the user authorized just after timeout.

Common situations: Backgrounded app where the user forgot to finish; user got distracted mid-login; clock differences making the deadline trigger early.

Understand the failure class

Related errors


AI-assisted analysis of chatboxai/chatbox@81571269ad (2026-08-12). Data as JSON: /api/errors/77c05e7d34add5a8. Report an issue: GitHub.

Appendix: source

Thrown at src/main/oauth/providers/github-copilot.ts:128

          // Use the GitHub access token directly as the Copilot API credential
          // (same approach as openllmprovider)
          return {
            accessToken: raw.access_token,
            // No refresh token — the GitHub access token doesn't expire
            // but the Copilot API session may need re-auth periodically
          }
        }

        if (raw.error === 'authorization_pending') continue
        if (raw.error === 'slow_down') {
          intervalMs += 5000
          continue
        }

        throw new Error(`Device flow failed: ${raw.error}`)
      }

      throw new Error('Device flow timed out')
    } finally {
      pendingDeviceCode = null
    }
  },

  async refreshToken(credentials) {
    // GitHub access tokens from device flow don't expire in the traditional sense.
    // Just return the existing credentials.
    return credentials
  },
}

View on GitHub (pinned to 81571269ad)