Egonex-AI/Understand-Anything · error · Error
Benchmark report files must share a directory
Error message
Benchmark report files must share a directory
What it means
Thrown by reportPairLockPath before the report transaction begins. The atomic delivery design writes the JSON report and the Markdown report as a pair in one directory, using a single advisory lock file whose key is derived from the directory. For the lock to be meaningful and for the rename-based install step to stay within one filesystem, both target files must live in the same physical directory (case-insensitively compared on win32).
Source
Thrown at scripts/lib/large-repo-benchmark.mjs:842
recovery.restoreFailures += 1;
}
} else if (!entry.hadOriginal && entry.installAttempted) {
if (!tryRemove(entry.targetPath, fileSystem)) {
recovery.rollbackRemoveFailures += 1;
}
}
}
export function reportPairLockPath(outputPath, markdownPath) {
const outputDirectory = canonicalizePhysicalPath(dirname(outputPath));
const markdownDirectory = canonicalizePhysicalPath(dirname(markdownPath));
const normalizePairPath = (pathValue) =>
process.platform === 'win32' ? pathValue.toLowerCase() : pathValue;
if (
normalizePairPath(outputDirectory) !==
normalizePairPath(markdownDirectory)
) {
throw new Error('Benchmark report files must share a directory');
}
const normalizedOutputPath = normalizePairPath(
canonicalizePhysicalPath(outputPath),
);
const normalizedMarkdownPath = normalizePairPath(
canonicalizePhysicalPath(markdownPath),
);
const pairKey = createHash('sha256')
.update(normalizedOutputPath)
.update('\0')
.update(normalizedMarkdownPath)
.digest('hex')
.slice(0, 24);
return join(resolve(dirname(outputPath)), `.ua-report-pair-${pairKey}.lock`);
}
function stageReportEntry(entry, fileSystem) {
let descriptor;View on GitHub (pinned to 32944829e7)
Solutions
- Put both report files in the same directory: --output ./reports/bench.json --markdown ./reports/bench.md.
- If you need them in different locations, run the benchmark twice or copy one file after delivery instead of passing divergent paths.
- Resolve symlinks with realpath before passing paths, since the comparison canonicalizes through realpath — a symlink that points outside the shared dir will trigger this.
Example fix
// before — different directories --output ./out/bench.json --markdown ./docs/bench.md // after — same directory --output ./reports/bench.json --markdown ./reports/bench.md
Defensive patterns
Strategy: validation
Validate before calling
import { realpathSync } from 'node:fs';
import { dirname } from 'node:path';
function ensureReportPairSharesDir(outputPath, markdownPath) {
const norm = (p) => process.platform === 'win32'
? realpathSync(dirname(p)).toLowerCase()
: realpathSync(dirname(p));
if (norm(outputPath) !== norm(markdownPath)) {
throw new Error('output and markdown must share one physical directory');
}
} Try / catch
try {
deliverBenchmarkReports(opts);
} catch (e) {
if (/must share a directory/.test(e.message)) {
console.error('Pass --output and --markdown in the same directory.');
}
throw e;
} Prevention
- Keep --output and --markdown in the same folder.
- Resolve symlinks with realpath before passing paths, since the comparison canonicalizes them.
- If you need separate locations, copy the file after a successful delivery rather than passing divergent paths.
When it happens
Trigger: deliverBenchmarkReports is invoked with outputPath and markdownPath whose dirname values differ after canonicalizePhysicalPath (realpath) and win32 lowercasing. For example --output ./out/a.json --markdown ./other/b.md, or one path symlinked such that realpath resolves to a different directory than the other.
Common situations: User supplies --output and --markdown in different folders by mistake. One path goes through a symlink that realpath resolves elsewhere. Mixing an absolute path for one and a relative path for the other that land in different cwd-relative dirs. Windows case differences (Out vs out) that the lowercasing does reconcile, but genuine different directories do not.
Related errors
- A benchmark report target is a directory
- A report transaction path already exists
- Unable to write benchmark report files
- Unable to remove temporary benchmark artifacts
- Repository path does not exist: ${repoValue}
AI-assisted analysis of Egonex-AI/Understand-Anything@32944829e7 (2026-08-12).
Data as JSON: /api/errors/1b1534bc34b30433.
Report an issue: GitHub.