eyaltoledano/claude-task-master · error

Failed to load workflow state: ${error.message}

Error message

Failed to load workflow state: ${error.message}

What it means

WorkflowStateManager.load() wraps any non-ENOENT failure (permission denied, invalid JSON from JSON.parse, EACCES, EISDIR) as a plain Error `Failed to load workflow state: <message>`. It distinguishes real load/parse problems from the benign 'file not found' case.

Source

Thrown at packages/tm-core/src/modules/workflow/managers/workflow-state-manager.ts:123

			await fs.access(this.statePath);
			return true;
		} catch {
			return false;
		}
	}

	/**
	 * Load workflow state from disk
	 */
	async load(): Promise<WorkflowState> {
		try {
			const content = await fs.readFile(this.statePath, 'utf-8');
			return JSON.parse(content) as WorkflowState;
		} catch (error: any) {
			if (error.code === 'ENOENT') {
				throw new Error(`Workflow state file not found at ${this.statePath}`);
			}
			throw new Error(`Failed to load workflow state: ${error.message}`);
		}
	}

	/**
	 * Save workflow state to disk
	 * Uses steno for atomic writes and automatic queueing of concurrent saves
	 */
	async save(state: WorkflowState): Promise<void> {
		try {
			// Ensure writer is initialized (creates directory if needed)
			await this.ensureWriter();

			// Serialize and validate JSON
			const jsonContent = JSON.stringify(state, null, 2);

			// Validate that the JSON is well-formed by parsing it back
			try {
				JSON.parse(jsonContent);

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Read the embedded original message to decide: JSON SyntaxError → repair/validate the file; EACCES → fix permissions
  2. Validate the JSON with `JSON.parse(fs.readFileSync(statePath,'utf8'))` manually and fix syntax errors
  3. Restore the state file from backup or delete it and let the workflow recreate it via save()
  4. Check ownership/permissions (chmod/chown) and that statePath is a file, not a directory

Example fix

// before
const state = await stateManager.load(); // opaque: Failed to load workflow state: Unexpected token
// after
try {
  const state = await stateManager.load();
} catch (e) {
  if (e instanceof SyntaxError || String(e.message).includes('Unexpected token')) {
    await stateManager.save(DEFAULT_WORKFLOW_STATE); // reset corrupt state
  } else throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

import { readFileSync } from 'fs';
try { JSON.parse(readFileSync(statePath, 'utf8')); }
catch (e) { /* corrupt or unreadable — reset or repair before load() */ }

Type guard

const isLoadFailure = (e: unknown) =>
  e instanceof Error && e.message.startsWith('Failed to load workflow state:');

Try / catch

try {
  state = await stateManager.load();
} catch (e) {
  if (isLoadFailure(e)) {
    await stateManager.save(DEFAULT_WORKFLOW_STATE); // reset corrupt state
    state = DEFAULT_WORKFLOW_STATE;
  } else throw e;
}

Prevention

When it happens

Trigger: State file exists but contains invalid JSON (truncated by a crash, hand-edited); read permission denied; statePath is a directory; disk I/O error during fs.readFile.

Common situations: Killed process leaving a half-written state file; user manually editing the JSON and introducing a syntax error; restrictive permissions after copying the project as root or via a container volume mount.

Related errors


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