mastra-ai/mastra · error · FileNotFoundError

ENOENT

ENOENT

Error message

File not found: ${path}

What it means

readFile throws FileNotFoundError (code ENOENT) when the target path does not exist on disk. The raw Node ENOENT from fs.readFile is translated into this typed error so callers can branch on error.code === 'ENOENT' or instanceof FileNotFoundError. This is one of the most common filesystem errors and usually indicates a wrong path, wrong casing, or a file that was expected to have been created earlier.

Source

Thrown at packages/core/src/workspace/filesystem/local-filesystem.ts:404

    this.logger.debug('Reading file', { path: inputPath, encoding: options?.encoding });
    await this.ensureReady();
    const absolutePath = this.resolvePath(inputPath);
    await this.assertPathContained(absolutePath);

    try {
      const stats = await fs.stat(absolutePath);
      if (stats.isDirectory()) {
        throw new IsDirectoryError(inputPath);
      }

      if (options?.encoding) {
        return await fs.readFile(absolutePath, { encoding: options.encoding });
      }
      return await fs.readFile(absolutePath);
    } catch (error: unknown) {
      if (error instanceof IsDirectoryError) throw error;
      if (isEnoentError(error)) {
        throw new FileNotFoundError(inputPath);
      }
      throw error;
    }
  }

  async writeFile(inputPath: string, content: FileContent, options?: WriteOptions): Promise<void> {
    const contentSize = Buffer.isBuffer(content) ? content.length : content.length;
    this.logger.debug('Writing file', { path: inputPath, size: contentSize, recursive: options?.recursive });
    await this.ensureReady();
    this.assertWritable('writeFile');
    const absolutePath = this.resolvePath(inputPath);
    await this.assertPathContained(absolutePath);

    // When recursive is explicitly false, verify parent directory exists
    if (options?.recursive === false) {
      const dir = nodePath.dirname(absolutePath);
      const parentPath = nodePath.dirname(inputPath);
      try {

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Check existence first with stat or use list to confirm the exact filename (watch casing).
  2. Create the file before reading it, or return a default/empty value when it is optional.
  3. Catch FileNotFoundError (code ENOENT) and handle it as 'absent' rather than a hard failure when appropriate.
  4. Verify the workspace basePath and mount configuration point at the directory that actually contains the file.

Example fix

// before
const cfg = await fs.readFile('config.json', { encoding: 'utf8' }); // throws if missing
// after
let cfg: string;
try {
  cfg = await fs.readFile('config.json', { encoding: 'utf8' });
} catch (e) {
  if (e instanceof FileNotFoundError) cfg = '{}';
  else throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

try {
  await ws.stat(p);
} catch {
  return null; // or create the file, depending on semantics
}

Type guard

import { FileNotFoundError } from '@mastra/core/workspace/errors';
function isFileNotFoundError(e: unknown): e is FileNotFoundError {
  return e instanceof FileNotFoundError ||
    (e instanceof Error && 'code' in e && (e as { code?: string }).code === 'ENOENT');
}

Try / catch

try {
  return await ws.readFile(p, { encoding: 'utf8' });
} catch (e) {
  if (isFileNotFoundError(e)) return defaultValue; // optional file
  throw e;
}

Prevention

When it happens

Trigger: readFile (or the 'content' helper) with a path that was never created, was deleted, or has a typo/wrong casing; reading a file expected from a previous workflow step that failed silently; case-sensitive filesystems where 'Config.JSON' ≠ 'config.json'.

Common situations: Agent hallucinates or misremembers a filename; file created in a different basePath or mount than where it's read; CI environment lacks a file present locally; path built from untrimmed user input (whitespace/newline in filename).

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/fb7add3b2d05bc76. Report an issue: GitHub.