{"record":{"id":"9163b8e5880d900b","repo":"nexu-io/open-design","slug":"refusing-to-use-dangerous-output-directory-outpu","errorCode":null,"errorMessage":"Refusing to use dangerous output directory: {output_dir}. Choose a dedicated generated-bundle directory instead.","messagePattern":"Refusing to use dangerous output directory: (.+?)\\. Choose a dedicated generated-bundle directory instead\\.","errorType":"exception","errorClass":"SystemExit","httpStatus":null,"severity":"error","filePath":"skills/chat-motion-overlay/scripts/prepare_chat_overlay_bundle.py","lineNumber":57,"sourceCode":"\ndef repo_root() -> Path:\n    return skill_root().parent.parent\n\n\ndef bundle_marker_path(output_dir: Path) -> Path:\n    return output_dir / BUNDLE_MARKER\n\n\ndef validate_output_dir(output_dir: Path, force: bool) -> None:\n    dangerous_targets = {\n        Path.cwd().resolve(),\n        Path.home().resolve(),\n        repo_root(),\n        skill_root(),\n        template_dir(),\n    }\n    if output_dir in dangerous_targets:\n        raise SystemExit(\n            f\"Refusing to use dangerous output directory: {output_dir}. \"\n            \"Choose a dedicated generated-bundle directory instead.\"\n        )\n    if output_dir.exists() and force and not bundle_marker_path(output_dir).exists():\n        raise SystemExit(\n            f\"Refusing to overwrite unmanaged output directory: {output_dir}. \"\n            f\"Only directories containing {BUNDLE_MARKER} can be replaced with --force.\"\n        )\n\n\ndef copy_template(output_dir: Path, force: bool) -> None:\n    validate_output_dir(output_dir, force)\n    if output_dir.exists():\n        if not force:\n            raise SystemExit(f\"Output directory already exists: {output_dir}. Use --force to overwrite.\")\n        shutil.rmtree(output_dir)\n    shutil.copytree(template_dir(), output_dir)\n    bundle_marker_path(output_dir).write_text(\"generated by chat-motion-overlay\\n\", encoding=\"utf-8\")","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/skills/chat-motion-overlay/scripts/prepare_chat_overlay_bundle.py#L39-L75","documentation":"Thrown by validate_output_dir() in prepare_chat_overlay_bundle.py when the requested --output-dir resolves to one of the dangerous targets: cwd, home, repo root, skill root, or the remotion-template directory. The bundle preparation step deletes and re-creates the output dir, so these locations would destroy user data or the skill itself.","triggerScenarios":"Run prepare_chat_overlay_bundle.py with --output-dir set to '.', '~', the repository root, the skill folder, or the assets/remotion-template folder (directly or via a symlink/relative path that resolves there). The run_test_matrix.py case 'invalid_force_dangerous_output_dir' passes the skill root to exercise this.","commonSituations":"Passing '.' or an empty-ish path expecting 'current dir is fine'; pointing output at the skill to 'overwrite in place'; a wrapper script that computes output_dir from a variable that happens to resolve to home.","solutions":["Point --output-dir at a dedicated generated-bundle directory such as ./.tmp/chat-overlay-bundle or a project-local build folder.","If the path comes from a variable, resolve and log it before invoking the script to confirm it is not a protected location.","Keep bundle output outside the skill and repo trees entirely (e.g. a dist/ or out/ folder)."],"exampleFix":"# before\npython prepare_chat_overlay_bundle.py --output-dir . --force\n# after\npython prepare_chat_overlay_bundle.py --output-dir ./.tmp/chat-overlay-bundle --force","handlingStrategy":"validation","validationCode":"from pathlib import Path\ndef assert_safe_output_dir(output_dir: Path, repo_root: Path, skill_root: Path) -> None:\n    out = output_dir.resolve()\n    dangerous = {Path.cwd().resolve(), Path.home().resolve(), repo_root.resolve(), skill_root.resolve(), (skill_root / \"assets\" / \"remotion-template\").resolve()}\n    if out in dangerous:\n        raise SystemExit(f\"refusing dangerous output dir {out}\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always point bundle output at a dedicated disposable directory.","Resolve and print output_dir in wrapper scripts before invoking the tool."],"tags":["filesystem-safety","chat-motion-overlay","bundle-prep"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}