eyaltoledano/claude-task-master · error

${authResult.error || 'Interactive authentication failed'}

Error message

${authResult.error || 'Interactive authentication failed'}

What it means

updateSingleTaskStatus validates newStatus with isValidTaskStatus against the allowed TASK_STATUS_OPTIONS and throws when the value is not one of them. Statuses are a closed enum, so any unknown string is rejected before touching task data.

Source

Thrown at apps/cli/src/commands/loop.command.ts:168

		if (authCheck.error) {
			throw new Error(authCheck.error);
		}

		if (authCheck.ready) {
			console.log(chalk.green('✓ Sandbox ready'));
			return;
		}

		console.log(
			chalk.yellow(
				'Sandbox needs authentication. Starting interactive session...'
			)
		);
		console.log(chalk.dim('Please complete auth, then Ctrl+C to continue.\n'));

		const authResult = this.tmCore.loop.runInteractiveAuth();
		if (!authResult.success) {
			throw new Error(authResult.error || 'Interactive authentication failed');
		}
		console.log(chalk.green('✓ Auth complete\n'));
	}

	private validateIterations(iterations: string): void {
		const parsed = Number(iterations);
		if (!Number.isInteger(parsed) || parsed < 1) {
			throw new Error(
				`Invalid iterations: ${iterations}. Must be a positive integer.`
			);
		}
	}

	private createOutputCallbacks(): LoopOutputCallbacks {
		return {
			onIterationStart: (iteration: number, total: number) => {
				console.log();
				console.log(chalk.cyan(`━━━ Iteration ${iteration} of ${total} ━━━`));

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Use an exact valid status from TASK_STATUS_OPTIONS (e.g. 'done' instead of 'complete')
  2. Log/print TASK_STATUS_OPTIONS (or run task-master --help) to see allowed values
  3. Normalize input (lowercase, trim) and validate with isValidTaskStatus before calling

Example fix

// before
await setTaskStatus(tasksPath, '5', 'complete');
// after
await setTaskStatus(tasksPath, '5', 'done');
Defensive patterns

Strategy: validation

Validate before calling

const TASK_STATUS_OPTIONS = ['pending','in-progress','done','deferred','cancelled'];
const normalized = String(newStatus || '').toLowerCase().trim();
if (!TASK_STATUS_OPTIONS.includes(normalized)) {
  throw new Error(`Invalid status "${newStatus}". Use: ${TASK_STATUS_OPTIONS.join(', ')}`);
}

Type guard

type TaskStatus = 'pending'|'in-progress'|'done'|'deferred'|'cancelled';
const isTaskStatus = (v: unknown): v is TaskStatus =>
  typeof v === 'string' && ['pending','in-progress','done','deferred','cancelled'].includes(v);

Try / catch

try {
  await setTaskStatus(tasksPath, taskId, newStatus);
} catch (e) {
  if (e.message.includes('Invalid status value')) {
    throw new Error(`Allowed statuses: pending, in-progress, done... (got "${newStatus}")`);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling updateSingleTaskStatus (via setTaskStatus / `task-master set-status`) with newStatus like 'complete', 'in_progress', 'todo', or any casing variant not in the allowed options list.

Common situations: Version drift where scripts use status strings from an older Task Master release; confusing task-master statuses with other trackers' vocabularies ('todo'/'done'); case mismatches like 'InProgress'.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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