eyaltoledano/claude-task-master · error · AuthenticationError
POLL_FAILED
POLL_FAILED
Error message
errorData.message || `HTTP ${response.status}` What it means
AuthenticationError thrown when the flow-status poll returns any non-2xx, non-404 status. It carries the server-provided error message when the body parses as JSON, otherwise the raw HTTP status, and terminates the polling loop for the authentication flow.
Source
Thrown at packages/tm-core/src/modules/auth/services/oauth-service.ts:345
method: 'GET',
headers: {
'User-Agent': `TaskMasterCLI/${this.getCliVersion()}`
}
});
if (!response.ok) {
const errorData = (await response.json().catch(() => ({}))) as {
message?: string;
};
if (response.status === 404) {
throw new AuthenticationError(
'Authentication flow expired or not found',
'FLOW_NOT_FOUND'
);
}
throw new AuthenticationError(
errorData.message || `HTTP ${response.status}`,
'POLL_FAILED'
);
}
const data = (await response.json()) as FlowStatusResponse;
if (!data.success) {
throw new AuthenticationError(
data.message || 'Failed to check status',
'POLL_FAILED'
);
}
switch (data.status) {
case 'complete': {
// Decrypt tokens using our private key
if (!data.encrypted_tokens) {View on GitHub (pinned to c0c98d367c)
Solutions
- Read the message (server error text or HTTP status) and address the indicated cause server-side.
- On 429, increase the polling interval or reduce concurrent logins, then retry the flow.
- On 5xx, retry after a short wait or restart the authentication flow if the backend remains unhealthy.
- Check backend/gateway logs around the failure time to identify the upstream error.
- Confirm no auth middleware in front of /api/auth/cli/status is rejecting unauthenticated CLI requests.
Example fix
// before: aggressive polling
await oauth.pollForCompletion(flowId, 60000); // polls every ~1s -> 429 POLL_FAILED
// after: catch, inspect status, retry with backoff or restart
try {
await oauth.pollForCompletion(flowId, 60000);
} catch (e) {
if (e.code === 'POLL_FAILED' && e.message.includes('429')) {
await new Promise(r => setTimeout(r, 5000));
await oauth.pollForCompletion(flowId, 60000);
}
} Defensive patterns
Strategy: try-catch
Type guard
function isPollFailed(e: unknown): e is AuthenticationError {
return e instanceof AuthenticationError && (e as any).code === 'POLL_FAILED';
} Try / catch
try {
await oauth.pollForCompletion(flowId, timeout);
} catch (e) {
if (isPollFailed(e)) {
if (/429/.test(e.message)) {
await new Promise(r => setTimeout(r, 5000)); // back off on rate limit
} else {
console.error(`Poll failed: ${e.message} — check auth server health`);
}
}
} Prevention
- Use conservative polling intervals to avoid server rate limits (429)
- Monitor auth server health/deployments during login windows
- Check gateway/proxy logs when seeing 5xx statuses mid-login
- Retry on transient 5xx/429; restart the flow for persistent failures
When it happens
Trigger: pollForCompletion receives response.ok === false with a status other than 404 — e.g. 401 from expired proxy credentials, 429 rate limiting from polling too aggressively, 500/502/503 from backend errors or a failing proxy.
Common situations: Long polling intervals too short hitting server rate limits; backend deployment or outage mid-login; gateway/ingress returning 502 during upstream restarts; auth service requiring a session/cookie the CLI doesn't send.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29).
Data as JSON: /api/errors/f2c6a8fd1d6bf239.
Report an issue: GitHub.