eyaltoledano/claude-task-master · error · Error

Error: Invalid status value: ${newStatus}. Use one of: ${TAS

Error message

Error: Invalid status value: ${newStatus}. Use one of: ${TASK_STATUS_OPTIONS.join(', ')}

What it means

setTaskStatus validates the requested status against isValidTaskStatus and the TASK_STATUS_OPTIONS list before touching any files. If newStatus is not one of the allowed enum values, it throws immediately. This guards against typos and unsupported custom statuses.

Source

Thrown at scripts/modules/task-manager/set-task-status.js:36

} from '../utils.js';
import updateSingleTaskStatus from './update-single-task-status.js';

/**
 * Set the status of a task
 * @param {string} tasksPath - Path to the tasks.json file
 * @param {string} taskIdInput - Task ID(s) to update
 * @param {string} newStatus - New status
 * @param {Object} options - Additional options (mcpLog for MCP mode, projectRoot for tag resolution)
 * @param {string} [options.projectRoot] - Project root path
 * @param {string} [options.tag] - Optional tag to override current tag resolution
 * @param {string} [options.mcpLog] - MCP logger object
 * @returns {Object|undefined} Result object in MCP mode, undefined in CLI mode
 */
async function setTaskStatus(tasksPath, taskIdInput, newStatus, options = {}) {
	const { projectRoot, tag } = options;
	try {
		if (!isValidTaskStatus(newStatus)) {
			throw new Error(
				`Error: Invalid status value: ${newStatus}. Use one of: ${TASK_STATUS_OPTIONS.join(', ')}`
			);
		}
		// Determine if we're in MCP mode by checking for mcpLog
		const isMcpMode = !!options?.mcpLog;

		// Only display UI elements if not in MCP mode
		if (!isMcpMode) {
			console.log(
				boxen(chalk.white.bold(`Updating Task Status to: ${newStatus}`), {
					padding: 1,
					borderColor: 'blue',
					borderStyle: 'round'
				})
			);
		}

		log('info', `Reading tasks from ${tasksPath}...`);

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Use a valid status exactly as listed by the error: pending, in-progress, done, deferred, cancelled, etc.
  2. Lowercase and normalize the status string before calling the API
  3. Check the project's TASK_STATUS_OPTIONS configuration if custom statuses were added

Example fix

// before
await setTaskStatus(path, '1', 'In Progress');
// after
await setTaskStatus(path, '1', 'in-progress');
Defensive patterns

Strategy: validation

Validate before calling

const VALID = ['pending', 'in-progress', 'done', 'deferred', 'cancelled'];
if (!VALID.includes(newStatus)) {
  throw new Error(`Status must be one of: ${VALID.join(', ')}; got '${newStatus}'`);
}

Type guard

function isValidStatus(s) {
  return typeof s === 'string' && ['pending', 'in-progress', 'done', 'deferred', 'cancelled'].includes(s);
}

Try / catch

try {
  await setTaskStatus(tasksPath, id, status);
} catch (err) {
  if (err.message.startsWith('Error: Invalid status value')) {
    console.error(`'${status}' is invalid; use: pending|in-progress|done|deferred|cancelled`);
  } else throw err;
}

Prevention

When it happens

Trigger: Calling setTaskStatus (or setTaskStatusDirect / the MCP result path) with newStatus values like 'done ', 'in-progress' when the vocabulary expects 'in_progress', 'completed', 'Done', or an arbitrary custom status string.

Common situations: Case or separator typos ('In-Progress' vs 'in-progress'); scripting with statuses from another tracker (Jira's 'To Do'); old versions using a different status vocabulary.

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/0c576766077de326. Report an issue: GitHub.