{"record":{"id":"838d95322d67774c","repo":"headroomlabs-ai/headroom","slug":"output-directory-must-be-empty-to-avoid-stale-arti-838d95","errorCode":null,"errorMessage":"output directory must be empty to avoid stale artifacts: {path}","messagePattern":"output directory must be empty to avoid stale artifacts: (.+?)","errorType":"exception","errorClass":"SystemExit","httpStatus":null,"severity":"error","filePath":"scripts/release_smoke_all.py","lineNumber":50,"sourceCode":"        return tomllib.load(fh)[\"project\"][\"version\"]\n\n\ndef quote_arg(value: str | os.PathLike[str]) -> str:\n    text = str(value)\n    if re.fullmatch(r\"[A-Za-z0-9_./:=\\\\-]+\", text):\n        return text\n    return f'\"{text.replace(chr(34), chr(34) * 2)}\"'\n\n\ndef run(args: list[str | os.PathLike[str]]) -> None:\n    print(\"\\n> \" + \" \".join(quote_arg(arg) for arg in args), flush=True)\n    subprocess.run([str(arg) for arg in args], cwd=ROOT, check=True)\n\n\ndef ensure_empty_dir(path: Path) -> None:\n    path.mkdir(parents=True, exist_ok=True)\n    if any(path.iterdir()):\n        raise SystemExit(f\"output directory must be empty to avoid stale artifacts: {path}\")\n\n\ndef parse_args() -> argparse.Namespace:\n    version = load_project_version()\n    stamp = datetime.now().strftime(\"%Y%m%d-%H%M%S\")\n    default_out = ROOT / \"release-assets-local\" / f\"all-{version}-{stamp}\"\n\n    parser = argparse.ArgumentParser(description=\"Run local npm and Python release smokes.\")\n    parser.add_argument(\"--out\", type=Path, default=default_out)\n    parser.add_argument(\"--python\", default=sys.executable)\n    parser.add_argument(\"--node\", default=shutil.which(\"node\") or \"node\")\n    parser.add_argument(\n        \"--python-release\",\n        action=\"store_true\",\n        help=\"Run the Python smoke with maturin --release instead of the faster ci profile.\",\n    )\n    parser.add_argument(\"--skip-npm\", action=\"store_true\")\n    parser.add_argument(\"--skip-python\", action=\"store_true\")","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/headroomlabs-ai/headroom/blob/322425c43bffde1ed0b64fecf3cf5951565dd82b/scripts/release_smoke_all.py#L32-L68","documentation":"Same guard as the Python smoke's ensure_empty_dir(), but in the top-level orchestrator scripts/release_smoke_all.py: it creates the run's output directory and refuses to continue if it is non-empty, so a run's summary never mixes artifacts from different runs.","triggerScenarios":"Passing `--out <dir>` that already contains files. The default output path embeds version + a `%Y%m%d-%H%M%S` timestamp, so the default essentially never collides — hitting this error almost always means an explicit `--out` was reused.","commonSituations":"Scripting repeated smokes with a fixed `--out ./out`; CI caching the output directory between attempts; a prior run crashing after writing partial results.","solutions":["Drop `--out` and let the script use its timestamped default directory.","Or remove/rename the existing directory before rerunning: `rm -rf <out_dir>`.","In CI, use a unique directory per attempt (`out-$GITHUB_RUN_ATTEMPT`) instead of a fixed path."],"exampleFix":"# before\npython scripts/release_smoke_all.py --out ./release-out\n# second run fails\n\n# after\npython scripts/release_smoke_all.py  # default: release-assets-local/all-<version>-<stamp>","handlingStrategy":"validation","validationCode":"from pathlib import Path\nimport sys\n\ndef ensure_runnable(out_dir: Path, skip_npm: bool, skip_python: bool) -> None:\n    if skip_npm and skip_python:\n        raise SystemExit(\"nothing to run: at least one smoke must be enabled\")\n    out_dir.mkdir(parents=True, exist_ok=True)\n    if any(out_dir.iterdir()):\n        raise SystemExit(f\"stale output dir: {out_dir}\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer the script's timestamped default --out over a fixed path.","Validate flag combinations at the top of wrapper scripts before delegating.","In CI, use run-attempt-unique output directories."],"tags":["release","smoke-test","filesystem","cli"],"backgroundTag":null,"analyzedSha":"322425c43bffde1ed0b64fecf3cf5951565dd82b","analyzedAt":"2026-08-15T01:03:05.481Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}