Hmbown/CodeWhale · error · Error
Output directory must be empty: ${outputDirectory}
Error message
Output directory must be empty: ${outputDirectory} What it means
assemble() refuses to write into an OUTPUT_DIR that already contains any entries. Because it generates the checksum manifest over the final file set, a non-empty target could mix stale or foreign bytes into a shipped release, so it fails fast before copying anything.
Source
Thrown at scripts/release/assemble-release-assets.js:143
let sourceStat;
try {
sourceStat = await fs.lstat(source);
} catch (error) {
if (error && error.code === "ENOENT") {
throw new Error(`Downloaded release artifacts are missing ${name} at ${source}`);
}
throw error;
}
if (!sourceStat.isFile()) {
throw new Error(`Downloaded release artifact must be a regular file: ${source}`);
}
sources.set(name, source);
}
await fs.mkdir(outputDirectory, { recursive: true });
const existing = await fs.readdir(outputDirectory);
if (existing.length > 0) {
throw new Error(`Output directory must be empty: ${outputDirectory}`);
}
for (const name of copiedNames) {
await fs.copyFile(sources.get(name), path.join(outputDirectory, name));
}
await fs.writeFile(
path.join(outputDirectory, WINDOWS_LAUNCHER),
windowsLauncherContents(),
"utf8",
);
const checksumRows = [];
for (const name of [...checksummedReleaseAssetNames()].sort()) {
checksumRows.push(`${await sha256(path.join(outputDirectory, name))} ${name}`);
}
await fs.writeFile(
path.join(outputDirectory, CHECKSUM_MANIFEST),
`${checksumRows.join("\n")}\n`,View on GitHub (pinned to 8880682c63)
Solutions
- Use a fresh empty directory: rm -rf release-out && node scripts/release/assemble-release-assets.js INPUT_DIR release-out
- In CI, use a unique run-scoped path such as $RUNNER_TEMP/release-assets
- Double-check argument order: INPUT_DIR (downloaded artifacts) first, OUTPUT_DIR second
Example fix
# before: second run reuses a non-empty output dir -> error node scripts/release/assemble-release-assets.js artifacts-in release-out # after rm -rf release-out node scripts/release/assemble-release-assets.js artifacts-in release-out
Defensive patterns
Strategy: validation
Validate before calling
#!/usr/bin/env bash # CI pre-step: guarantee a clean output dir before assemble OUT="$RUNNER_TEMP/release-assets" rm -rf "$OUT" && mkdir -p "$OUT" node scripts/release/assemble-release-assets.js "$ARTIFACTS_IN" "$OUT"
Prevention
- Create the output directory fresh in the same command that runs assemble (rm -rf && mkdir -p)
- Use runner-temp paths unique per job instead of workspace-relative output dirs
- Never reuse a release output directory across attempts; each assemble run starts from empty
When it happens
Trigger: Re-running assemble into the same OUTPUT_DIR used by a previous attempt; passing a directory that already holds files (workspace dir, a folder with a README); pointing OUTPUT_DIR at INPUT_DIR by mistake.
Common situations: Retrying a failed release without cleaning the output directory; a CI step that pre-populates the output path; copy-paste invoking with in and out swapped.
Related errors
- Release asset directory must be flat; found: ${nonFiles.map(
- Downloaded release artifacts are missing ${name} at ${source
- ${label} does not match the authoritative inventory; missing
- Downloaded release artifact must be a regular file: ${source
- CODEWHALE_SMOKE_ASSETS_DIR is not a directory: ${releaseAsse
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/604e4106c3f93dd8.
Report an issue: GitHub.