eyaltoledano/claude-task-master · error

Input file ${prdPath} is empty or could not be read.

Error message

Input file ${prdPath} is empty or could not be read.

What it means

readPrdContent reads the PRD file synchronously with fs.readFileSync(prdPath, 'utf8') and throws a plain Error when the result is falsy (empty string). This catches zero-byte files and certain read failures surfaced as empty content, ensuring parse-prd never proceeds with no input. Note fs.readFileSync throws its own ENOENT/EISDIR errors for missing files, so this specific message usually means the file exists but is empty.

Source

Thrown at scripts/modules/task-manager/parse-prd/parse-prd-helpers.js:35

 * Estimate token count from text
 * @param {string} text - Text to estimate tokens for
 * @returns {number} Estimated token count
 */
export function estimateTokens(text) {
	// Common approximation: ~4 characters per token for English
	return Math.ceil(text.length / 4);
}

/**
 * Read and validate PRD content
 * @param {string} prdPath - Path to PRD file
 * @returns {string} PRD content
 * @throws {Error} If file is empty or cannot be read
 */
export function readPrdContent(prdPath) {
	const prdContent = fs.readFileSync(prdPath, 'utf8');
	if (!prdContent) {
		throw new Error(`Input file ${prdPath} is empty or could not be read.`);
	}
	return prdContent;
}

/**
 * Load existing tasks from file
 * @param {string} tasksPath - Path to tasks file
 * @param {string} targetTag - Target tag to load from
 * @returns {{tasks: Array, nextId: number}} Existing tasks and next ID
 */
export function loadExistingTasks(tasksPath, targetTag) {
	let existingTasks = [];
	let nextId = 1;

	if (!fs.existsSync(tasksPath)) {
		return { existingTasks, nextId };
	}

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Check the file is non-empty: `wc -c prd.txt` or fs.statSync size > 0, then add content and retry.
  2. Verify the resolved path is the intended PRD (log prdPath before calling).
  3. If the file doesn't exist you'll get ENOENT instead — create the PRD file first.
  4. Fix CI artifact steps so the PRD is generated before parse-prd runs.
  5. Guard the call: validate file existence and size before invoking readPrdContent.

Example fix

// before
const content = readPrdContent(prdPath); // throws on empty file
// after
import fs from 'fs';
if (!fs.existsSync(prdPath) || fs.statSync(prdPath).size === 0) {
  throw new Error(`PRD at ${prdPath} is missing or empty; add content first.`);
}
const content = readPrdContent(prdPath);
Defensive patterns

Strategy: validation

Validate before calling

import fs from 'fs';
if (!fs.existsSync(prdPath) || fs.statSync(prdPath).size === 0) {
  throw new Error(`PRD file ${prdPath} is missing or empty.`);
}

Type guard

function isReadableNonEmptyFile(path) {
  try {
    const st = fs.statSync(path);
    return st.isFile() && st.size > 0;
  } catch {
    return false;
  }
}

Try / catch

try {
  const content = readPrdContent(prdPath);
} catch (e) {
  if (e.message.includes('is empty or could not be read')) {
    console.error(`PRD at ${prdPath} is empty; provide content before parsing.`);
  } else throw e;
}

Prevention

When it happens

Trigger: Passing a PRD path to a zero-byte file; a path to a directory or unreadable file in environments where readFileSync returns empty; shell redirection creating an empty file before parse (e.g. `> prd.txt` then parsing); variable expansion producing an empty path that resolves oddly.

Common situations: CI pipelines where the PRD artifact failed to upload/download; users creating the PRD file but forgetting to save content; typo'd env var (PRD_PATH=) combined with fallback path resolution; Windows/Unix path issues pointing at the wrong file.

Related errors


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