eyaltoledano/claude-task-master · error

Invalid task ID format: ${invalidIds.join(', ')}. Expected n

Error message

Invalid task ID format: ${invalidIds.join(', ')}. Expected numeric (e.g., '15'), subtask (e.g., '15.2'), or display ID (e.g., 'HAM-123')

What it means

parseTaskIds() validates each comma-separated segment against isValidTaskIdFormat and throws `Invalid task ID format: <ids>` when any segment is not a numeric ID ('15'), subtask ID ('15.2'), or display ID ('HAM-123'). This prevents malformed IDs from reaching storage lookup.

Source

Thrown at packages/tm-core/src/modules/tasks/validation/task-id.ts:132

 * parseTaskIds("HAM-123");     // ["HAM-123"]
 * parseTaskIds("ham1,ham2");   // ["HAM-1", "HAM-2"] (normalized)
 * parseTaskIds("invalid");     // throws Error
 * parseTaskIds("HAM-1.2");     // throws Error (API subtasks not supported)
 * ```
 */
export function parseTaskIds(input: string): string[] {
	const ids = input
		.split(',')
		.map((id) => id.trim())
		.filter((id) => id.length > 0);

	if (ids.length === 0) {
		throw new Error('No valid task IDs provided');
	}

	const invalidIds = ids.filter((id) => !isValidTaskIdFormat(id));
	if (invalidIds.length > 0) {
		throw new Error(
			`Invalid task ID format: ${invalidIds.join(', ')}. Expected numeric (e.g., '15'), subtask (e.g., '15.2'), or display ID (e.g., 'HAM-123')`
		);
	}

	// Normalize all IDs (e.g., "ham1" → "HAM-1")
	return ids.map(normalizeDisplayId);
}

/**
 * Extract parent task ID from a subtask ID
 *
 * @param taskId - Task ID (e.g., "1.2.3")
 * @returns Parent ID (e.g., "1") or the original ID if not a subtask
 *
 * @example
 * ```typescript
 * extractParentId("1.2.3");  // "1"
 * extractParentId("1.2");    // "1"

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Correct the ID string: numeric (15), subtask (15.2), or display ID (HAM-123) — comma-separated, no quotes/brackets
  2. Normalize display-ID prefixes if needed (parser normalizes 'ham1' to 'HAM-1', but only after format validation)
  3. Pre-validate each ID with isValidTaskIdFormat() and show the user which entries were rejected

Example fix

// before
parseTaskIds('[15, 16]'); // Invalid task ID format: [15,  16]
// after
parseTaskIds('15,16'); // OK
Defensive patterns

Strategy: validation

Validate before calling

const TASK_ID_RE = /^\d+(\.\d+)?$|^[A-Za-z]+-\d+$/;
const bad = input.split(',').map(s => s.trim()).filter(s => s && !TASK_ID_RE.test(s));
if (bad.length) throw new Error(`Bad IDs: ${bad.join(', ')}`);
parseTaskIds(input);

Type guard

const isTaskId = (s: string) => /^\d+(\.\d+)?$|^[A-Z]+-\d+$/.test(s.trim());

Try / catch

try {
  ids = parseTaskIds(input);
} catch (e) {
  if (e.message.startsWith('Invalid task ID format')) {
    console.error(e.message); // shows offending IDs and expected formats
    process.exitCode = 1;
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling `parseTaskIds('abc')`, `parseTaskIds('15..2')`, `parseTaskIds('HAM_12')`, or any segment with stray characters (quotes, brackets, trailing dots).

Common situations: Pasting IDs with surrounding whitespace is fine, but pasting 'Task #15', '[15]', or '15.' is not; users mixing underscore vs hyphen in display IDs (HAM_123); programmatic callers concatenating IDs with wrong separators (space instead of comma).

Related errors


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