eyaltoledano/claude-task-master · error · Error
Invalid JSON in file ${filePath}: ${error.message}
Error message
Invalid JSON in file ${filePath}: ${error.message} What it means
readJson() parses a file with JSON.parse; when parsing fails with a SyntaxError the file exists but is not valid JSON, so a descriptive Error naming the file and parse message is thrown. ENOENT is deliberately re-thrown so callers can treat a missing file as 'no data' rather than corruption.
Source
Thrown at packages/tm-core/src/modules/storage/adapters/file-storage/file-operations.ts:63
writer = new Writer(filePath);
this.writers.set(filePath, writer);
}
return writer;
}
/**
* Read and parse JSON file
*/
async readJson(filePath: string): Promise<any> {
try {
const content = await fs.readFile(filePath, 'utf-8');
return JSON.parse(content);
} catch (error: any) {
if (error.code === 'ENOENT') {
throw error; // Re-throw ENOENT for caller to handle
}
if (error instanceof SyntaxError) {
throw new Error(`Invalid JSON in file ${filePath}: ${error.message}`);
}
throw new Error(`Failed to read file ${filePath}: ${error.message}`);
}
}
/**
* Write JSON file with atomic operation and cross-process locking.
* Uses steno for atomic writes and proper-lockfile for cross-process safety.
* WARNING: This replaces the entire file. For concurrent modifications,
* use modifyJson() instead to prevent lost updates.
*/
async writeJson(
filePath: string,
data: FileStorageData | any
): Promise<void> {
// Ensure file exists for locking (proper-lockfile requires this)
await this.ensureFileExists(filePath);
View on GitHub (pinned to c0c98d367c)
Solutions
- Open the file at the path in the message and fix the JSON syntax indicated by the parse error (line/column in error.message).
- If the file is unimportant or regenerable, restore it from git (git checkout -- <file>) or delete it so the storage layer recreates it.
- Validate the file with a parser (node -e "JSON.parse(require('fs').readFileSync('<path>','utf8'))") after editing to confirm it parses.
- Avoid hand-editing storage files while the app runs; use the CLI commands that go through modifyJson/writeJson atomic writes.
Example fix
// before (tasks.json contains a trailing comma)
{ "tasks": [ ... ], }
// after
{
"tasks": [ ... ]
} Defensive patterns
Strategy: validation
Validate before calling
import { readFileSync } from 'fs';
export function isValidJsonFile(filePath: string): boolean {
try { JSON.parse(readFileSync(filePath, 'utf-8')); return true; }
catch (err: any) { return err.code === 'ENOENT'; } // missing is OK, malformed is not
} Try / catch
try {
const data = await fileOps.readJson(filePath);
} catch (err: any) {
if (err.code === 'ENOENT') return defaultValue;
if (err.message.startsWith('Invalid JSON in file')) {
// offer backup restore or interactive repair
return recoverFromBackup(filePath) ?? defaultValue;
}
throw err;
} Prevention
- Never hand-edit storage JSON while the app is running; use CLI commands with atomic writes.
- Validate edited files with a JSON linter/formatter before saving.
- Keep storage files in git so corruption is recoverable via checkout.
- Resolve git merge conflicts in .taskmaster files before running commands.
When it happens
Trigger: Calling readJson (directly or via data/rawData/stateData accessors) on a file whose contents are truncated, hand-edited incorrectly, contain trailing commas/comments, or were written by another tool in a non-JSON format.
Common situations: A crashed or interrupted write left a partial file (outside this library's atomic steno writes); a user manually edited .taskmaster/tasks.json and broke syntax; merge conflict markers (<<<<<<<) left in the file; the file was saved with BOM or as YAML/JSON5.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Corrupted JSON in ${filePath}: ${err.message}. File contains
- Could not read or parse complexity report: ${reportError.mes
- Failed to parse JSON response: ${parseError.message}. Respon
- CONFIG_ERROR
- Failed to read file ${filePath}: ${error.message}
AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29).
Data as JSON: /api/errors/6affa0f5dfa3329c.
Report an issue: GitHub.