eyaltoledano/claude-task-master · error · Error

Failed to copy file from ${srcPath} to ${destPath}: ${error.

Error message

Failed to copy file from ${srcPath} to ${destPath}: ${error.message}

What it means

copyFile() wraps fs.copyFile(srcPath, destPath) failures into 'Failed to copy file from <src> to <dest>: <reason>'. copyFile does not create missing destination directories and overwrites an existing destination only if it can be written; any OS error (missing source, permissions, no space) is surfaced with both paths.

Source

Thrown at packages/tm-core/src/modules/storage/adapters/file-storage/file-operations.ts:271

	 */
	async moveFile(oldPath: string, newPath: string): Promise<void> {
		try {
			await fs.rename(oldPath, newPath);
		} catch (error: any) {
			throw new Error(
				`Failed to move file from ${oldPath} to ${newPath}: ${error.message}`
			);
		}
	}

	/**
	 * Copy file
	 */
	async copyFile(srcPath: string, destPath: string): Promise<void> {
		try {
			await fs.copyFile(srcPath, destPath);
		} catch (error: any) {
			throw new Error(
				`Failed to copy file from ${srcPath} to ${destPath}: ${error.message}`
			);
		}
	}

	/**
	 * Clean up resources - releases cached steno Writers
	 * Call this when the FileOperations instance is no longer needed
	 * to prevent memory leaks in long-running processes.
	 */
	async cleanup(): Promise<void> {
		// Clear cached Writers to allow garbage collection
		// Note: steno Writers don't have explicit close methods;
		// they handle file descriptor cleanup internally
		this.writers.clear();
	}
}

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Confirm the source file exists at srcPath; create or restore it before copying (ENOENT is the most frequent cause).
  2. Create the destination directory first: await fileOps.ensureDir(path.dirname(destPath)).
  3. Fix permissions (read on source, write on destination directory) indicated by EACCES in the message.
  4. Free disk space or quota if ENOSPC is reported, then retry the copy.

Example fix

// before
await fileOps.copyFile('.taskmaster/tasks/master.json', '.taskmaster/tasks/feature.json');
// ENOENT: .taskmaster/tasks/ dir missing
// after
await fileOps.ensureDir('.taskmaster/tasks');
await fileOps.copyFile('.taskmaster/tasks/master.json', '.taskmaster/tasks/feature.json');
Defensive patterns

Strategy: validation

Validate before calling

import { stat, access, constants } from 'fs/promises';
import path from 'path';
export async function canCopyFile(srcPath: string, destPath: string): Promise<boolean> {
  try {
    const s = await stat(srcPath);
    if (!s.isFile()) return false;
    await access(srcPath, constants.R_OK);
    await access(path.dirname(destPath), constants.W_OK);
    return true;
  } catch { return false; }
}

Try / catch

try {
  await fileOps.copyFile(srcPath, destPath);
} catch (err: any) {
  if (err.message.startsWith('Failed to copy file')) {
    console.error(`Copy failed: check source ${srcPath} exists/readable and destination dir is writable (${err.message})`);
    throw err;
  }
  throw err;
}

Prevention

When it happens

Trigger: copyFile invoked when the source file does not exist (ENOENT), the source or destination directory is missing (ENOENT on path components), permissions deny read/write (EACCES), or the destination volume is full (ENOSPC).

Common situations: Duplicating a tag's task file before the source was ever written; copying into a tag directory that hasn't been created yet; disk quota/full disk during large copies; read-only source or destination mounts in containers.

Related errors


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