eyaltoledano/claude-task-master · warning

Unknown flow status: ${data.status}

Error message

Unknown flow status: ${data.status}

What it means

While polling the OAuth device/flow endpoint for completion, the server returned a status string the client's switch statement doesn't recognize (it handles success, pending, expired, error, etc.). The client logs a warning and keeps polling rather than failing, so an unrecognized-but-terminal status could cause indefinite polling.

Source

Thrown at packages/tm-core/src/modules/auth/services/oauth-service.ts:411

							'OAUTH_FAILED'
						);

					case 'expired':
						throw new AuthenticationError(
							'Authentication flow expired',
							'AUTH_TIMEOUT'
						);

					case 'pending':
					case 'authenticating':
						// Still waiting, continue polling
						this.logger.debug(
							`Flow status: ${data.status}, continuing to poll`
						);
						break;

					default:
						this.logger.warn(`Unknown flow status: ${data.status}`);
				}
			} catch (error) {
				if (error instanceof AuthenticationError) {
					throw error;
				}

				// Log network errors but continue polling
				this.logger.debug('Poll request failed, will retry:', error);
			}

			// Wait before next poll
			await new Promise((resolve) => setTimeout(resolve, pollInterval));
		}

		throw new AuthenticationError('Authentication timeout', 'AUTH_TIMEOUT');
	}

	/**

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Update @tm-core / the CLI to the latest version so the poller recognizes current status values.
  2. Log the full polling response and align the client switch statement with the server's documented status enum.
  3. If the unknown status is terminal (e.g. 'cancelled'), abort polling and restart the auth flow instead of looping.
  4. Report the unexpected status value to the maintainers if server and client versions already match.

Example fix

// before
case 'expired': ... break;
default: this.logger.warn(`Unknown flow status: ${data.status}`);
// after
case 'expired': ... break;
case 'cancelled': case 'timeout': this.stopPolling(new AuthenticationError(`Flow ${data.status}`)); break;
default: this.logger.warn(`Unknown flow status: ${data.status}`);
Defensive patterns

Strategy: retry

Validate before calling

const KNOWN_STATUSES = ['success', 'pending', 'expired', 'error', 'processing'];
if (data.status && !KNOWN_STATUSES.includes(data.status)) {
  console.warn(`Unrecognized flow status '${data.status}'; verify server/client versions match.`);
}

Type guard

function isKnownFlowStatus(s) {
  return ['success', 'pending', 'expired', 'error', 'processing'].includes(s);
}

Try / catch

try {
  await pollForCompletion(flowId, { timeoutMs: 120_000 });
} catch (err) {
  if (err.name === 'PollTimeoutError') {
    console.warn('Polling did not reach a recognized terminal state; restarting auth flow.');
    await restartAuthFlow();
  }
}

Prevention

When it happens

Trigger: The flow status endpoint returns a new or localized status value — e.g. after a server API version bump introducing statuses like 'cancelled', 'timeout', or 'rate_limited' the older client doesn't map.

Common situations: Server/client version mismatch (updated backend, stale CLI); proxies returning nonstandard status bodies; a buggy server emitting typo'd status values; polling a flow whose authorization URL was generated by a newer client.

Related errors


AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29). Data as JSON: /api/errors/17c45f96fa134fbc. Report an issue: GitHub.