Egonex-AI/Understand-Anything · error · Error

A benchmark report target is a directory

Error message

A benchmark report target is a directory

What it means

Thrown by preflightReportTargets during the atomic report-delivery transaction. Before acquiring the pair lock or writing temp files, the harness checks each target path (the JSON output path and the markdown path); if any already exists and resolves to a directory, delivery aborts. This prevents the subsequent writeFileSync/renameSync from failing mid-transaction with EISDIR, which would leave backups stranded.

Source

Thrown at scripts/lib/large-repo-benchmark.mjs:802

}

function fileSizeOrZero(path) {
  try {
    return statSync(path).size;
  } catch {
    return 0;
  }
}

function writeJson(path, value) {
  mkdirSync(dirname(path), { recursive: true });
  writeFileSync(path, `${JSON.stringify(value, null, 2)}\n`, 'utf-8');
}

function preflightReportTargets(paths, fileSystem) {
  for (const path of paths) {
    if (fileSystem.existsSync(path) && fileSystem.statSync(path).isDirectory()) {
      throw new Error('A benchmark report target is a directory');
    }
  }
}

function tryRemove(path, fileSystem) {
  try {
    fileSystem.rmSync(path, { force: true });
    return true;
  } catch {
    return false;
  }
}

function rollbackReportEntry(entry, fileSystem, recovery) {
  if (entry.backupMoved) {
    if (!tryRemove(entry.targetPath, fileSystem)) {
      recovery.rollbackRemoveFailures += 1;
    }

View on GitHub (pinned to 32944829e7)

Solutions

  1. Pass explicit file paths (with .json and .md extensions) rather than a directory: --output ./reports/bench.json --markdown ./reports/bench.md.
  2. If you intended a directory, pre-create the file names inside it and reference those files directly.
  3. Remove or rename the directory currently occupying the target path: rm -rf <path> (only after confirming it is not needed).
  4. Check both --output and --markdown; the error fires on whichever resolves to a directory first.

Example fix

// before
node scripts/large-repo-benchmark.mjs --output ./reports --markdown ./reports

// after — point at files, not the directory
node scripts/large-repo-benchmark.mjs --output ./reports/bench.json --markdown ./reports/bench.md
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync, statSync } from 'node:fs';
function ensureReportTargetsAreFiles(paths) {
  for (const p of paths) {
    if (existsSync(p) && statSync(p).isDirectory()) {
      throw new Error(`Refusing to overwrite directory at ${p}; pass a file path.`);
    }
  }
}
// before calling deliverBenchmarkReports:
ensureReportTargetsAreFiles([options.outputPath, options.markdownPath]);

Try / catch

try {
  deliverBenchmarkReports(opts);
} catch (e) {
  if (e instanceof BenchmarkReportWriteError) {
    // preflight failures are not in recovery; surface the cause clearly
    console.error('report delivery preflight failed:', e.message);
  }
  throw e;
}

Prevention

When it happens

Trigger: deliverBenchmarkReports is called with outputPath and/or markdownPath that point at an existing directory (e.g. the user passed --output ./reports where ./reports is a folder). preflightReportTargets calls fs.existsSync then fs.statSync().isDirectory() on each and throws on the first directory hit.

Common situations: Passing a directory path as --output or --markdown (common when a user expects the tool to derive a filename inside it). A previous run created a file at that path which was later replaced by a directory. CI that mounts a directory volume at the output location. Shell completion appending a trailing slash that resolves to an existing dir.

Related errors


AI-assisted analysis of Egonex-AI/Understand-Anything@32944829e7 (2026-08-12). Data as JSON: /api/errors/13ef20a753011b1d. Report an issue: GitHub.