tinyhumansai/openhuman · warning · Error
Refusing to overwrite hidden file: ${outputPath}
Error message
Refusing to overwrite hidden file: ${outputPath} What it means
A write-guard in main(): when --output names a path that already exists AND basename(outputPath) starts with '.' (a dotfile such as .env, .gitignore, .release-notes.md), the script refuses to overwrite it, protecting hidden config files from being clobbered by generated Markdown.
Source
Thrown at scripts/release/generate-release-notes.mjs:703
});
const title = releaseTitle(from, options.to, resolvedTo);
let markdown;
if (options.dryRun) {
const request = buildOpenAiRequest({ model: options.model, title, payload });
markdown = JSON.stringify(request, null, 2);
} else if (options.noAi) {
markdown = renderDeterministicNotes({ title, payload });
} else {
const request = buildOpenAiRequest({ model: options.model, title, payload });
markdown = await summarizeWithOpenAi(request);
markdown = ensureAllPullRequestsLinked(markdown, payload.pullRequests);
}
if (options.output) {
const outputPath = resolve(options.output);
if (existsSync(outputPath) && basename(outputPath).startsWith('.')) {
throw new Error(`Refusing to overwrite hidden file: ${outputPath}`);
}
writeFileSync(outputPath, markdown.endsWith('\n') ? markdown : `${markdown}\n`);
console.error(`[release-notes] Wrote ${outputPath}`);
} else {
process.stdout.write(markdown.endsWith('\n') ? markdown : `${markdown}\n`);
}
}
if (import.meta.url === pathToFileURL(process.argv[1]).href) {
main().catch((error) => {
console.error(`[release-notes] ${error.message}`);
process.exit(1);
});
}
View on GitHub (pinned to a221052e0d)
Solutions
- Point --output at a regular, non-hidden filename (e.g. release-notes.md)
- If overwriting the hidden file is truly intended, remove or rename it yourself first — the script will not do it
Example fix
# before (hidden draft already exists → refused) node scripts/release/generate-release-notes.mjs --output .release-notes.md # after node scripts/release/generate-release-notes.mjs --output release-notes.md
Defensive patterns
Strategy: validation
Validate before calling
import { basename, resolve } from 'node:path';
import { existsSync } from 'node:fs';
const out = resolve(options.output);
if (existsSync(out) && basename(out).startsWith('.')) {
throw new Error(`refusing hidden output ${out}; choose a visible filename`);
} Prevention
- keep release notes in non-hidden paths
- treat the refusal as intentional — never script around it blindly
- validate scripted --output values against dotfiles before invocation
When it happens
Trigger: Passing --output .env, --output .draft.md, or any path where a hidden file already exists — typically a scripted or copy-pasted output path that collides with a dotfile. Writing a new hidden file is fine; only overwriting an existing one is refused.
Common situations: Shell variables or globs resolving to a dotfile; a stale hidden draft from an earlier experiment still sitting at the target; muscle-memory use of dot-prefixed scratch filenames.
Related errors
- RPC envelope contains undefined data
- Cannot reveal "${path}" on this device — it is a path on the
- empty transcript
- RPC token not found at ${tokenPath}. Pass --token or set OPE
- RPC token not provided and ${tokenPath} could not be read. P
AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16).
Data as JSON: /api/errors/6ca449d53051ad7d.
Report an issue: GitHub.