eyaltoledano/claude-task-master · error · MoveTaskError

ID_COUNT_MISMATCH

ID_COUNT_MISMATCH

Error message

Number of source IDs (${sourceIds.length}) must match number of destination IDs (${destinationIds.length})

What it means

moveTask supports batch moves by pairing comma-separated source and destination IDs (e.g. '5,6,7' -> '9,10,11'). Before processing, it requires both lists to have the same length so each source maps 1:1 to a destination; otherwise it throws MoveTaskError with code ID_COUNT_MISMATCH.

Source

Thrown at scripts/modules/task-manager/move-task.js:124

 * @param {Object} options - Additional options
 * @param {string} options.projectRoot - Project root directory for tag resolution
 * @param {string} options.tag - Explicit tag to use (optional)
 * @returns {Object} Result object with moved task details
 */
async function moveTask(
	tasksPath,
	sourceId,
	destinationId,
	generateFiles = false,
	options = {}
) {
	const { projectRoot, tag } = options;
	// Check if we have comma-separated IDs (batch move)
	const sourceIds = sourceId.split(',').map((id) => id.trim());
	const destinationIds = destinationId.split(',').map((id) => id.trim());

	if (sourceIds.length !== destinationIds.length) {
		throw new MoveTaskError(
			MOVE_ERROR_CODES.ID_COUNT_MISMATCH,
			`Number of source IDs (${sourceIds.length}) must match number of destination IDs (${destinationIds.length})`
		);
	}

	// For batch moves, process each pair sequentially
	if (sourceIds.length > 1) {
		const results = [];
		for (let i = 0; i < sourceIds.length; i++) {
			const result = await moveTask(
				tasksPath,
				sourceIds[i],
				destinationIds[i],
				false, // Don't generate files for each individual move
				options
			);
			results.push(result);
		}

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Make the destination list the same length as the source list, pairing each source with its destination
  2. If you want multiple tasks moved under one parent, perform separate calls or use the single-ID form with a subtask destination
  3. Trim whitespace and remove empty entries from both lists before calling (',,5' produces empty strings that still count)

Example fix

// before
task-master move --from="5,6,7" --to="9,10"
// after
task-master move --from="5,6,7" --to="9,10,11"
Defensive patterns

Strategy: validation

Validate before calling

function validateBatchMove(sourceId, destinationId) {
  const s = sourceId.split(',').map((x) => x.trim()).filter(Boolean);
  const d = destinationId.split(',').map((x) => x.trim()).filter(Boolean);
  if (s.length !== d.length) {
    throw new Error(`Batch move needs equal counts: ${s.length} sources vs ${d.length} destinations`);
  }
  return [s, d];
}

Type guard

const isPairedIdList = (s, d) =>
  s.split(',').filter((x) => x.trim()).length === d.split(',').filter((x) => x.trim()).length;

Try / catch

try {
  await moveTask(tasksPath, from, to, false, { projectRoot, tag });
} catch (err) {
  if (err.name === 'MoveTaskError' && err.code === 'ID_COUNT_MISMATCH') {
    console.error('Pair each source ID with a destination ID, e.g. --from=5,6 --to=9,10');
  } else throw err;
}

Prevention

When it happens

Trigger: Calling moveTask (or `task-master move --from=5,6 --to=7`) where sourceId.split(',') and destinationId.split(',') yield different counts, e.g. moving 3 sources to 2 destinations.

Common situations: Typo in a comma-separated list (dropped or extra ID); generating the lists programmatically and a source being filtered out before the call; misunderstanding that batch move is pairwise, not 'move all into one destination'.

Related errors


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