{"record":{"id":"341406c29ec513ef","repo":"github/spec-kit","slug":"integration-manifest-directory-path-is-not-a-direc","errorCode":null,"errorMessage":"Integration manifest directory path is not a directory: {label}","messagePattern":"Integration manifest directory path is not a directory: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/specify_cli/integrations/manifest.py","lineNumber":75,"sourceCode":"\ndef _ensure_safe_manifest_directory(root: Path, directory: Path) -> None:\n    \"\"\"Create a manifest directory without following symlinked parents.\"\"\"\n    root_resolved = root.resolve()\n    try:\n        rel = directory.relative_to(root)\n    except ValueError:\n        label = _manifest_path_label(root, directory)\n        raise ValueError(f\"Integration manifest directory escapes project root: {label}\") from None\n\n    current = root\n    for part in rel.parts:\n        current = current / part\n        label = _manifest_path_label(root, current)\n        if current.is_symlink():\n            raise ValueError(f\"Refusing to use symlinked integration manifest directory: {label}\")\n        if current.exists():\n            if not current.is_dir():\n                raise ValueError(f\"Integration manifest directory path is not a directory: {label}\")\n            try:\n                current.resolve().relative_to(root_resolved)\n            except (OSError, ValueError):\n                raise ValueError(f\"Integration manifest directory escapes project root: {label}\") from None\n            continue\n        current.mkdir()\n        try:\n            current.resolve().relative_to(root_resolved)\n        except (OSError, ValueError):\n            raise ValueError(f\"Integration manifest directory escapes project root: {label}\") from None\n\n\ndef _ensure_safe_manifest_destination(root: Path, path: Path) -> None:\n    \"\"\"Refuse manifest writes that would escape the project or follow symlinks.\"\"\"\n    root_resolved = root.resolve()\n    _ensure_safe_manifest_directory(root, path.parent)\n    label = _manifest_path_label(root, path)\n    if path.is_symlink():","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/github/spec-kit/blob/bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c/src/specify_cli/integrations/manifest.py#L57-L93","documentation":"Raised while creating the manifest directory chain when an existing path component is present but is a regular file, not a directory. The CLI cannot mkdir over a file, so it aborts rather than clobbering it.","triggerScenarios":"A file named .specify or .specify/integrations exists in the project when IntegrationManifest.save() tries to ensure the directory chain (e.g. someone created a .specify marker file, or a template rendered a file where a directory belongs).","commonSituations":"A stray file named .specify committed by a scaffolding tool or editor plugin; Case-insensitive filesystem collisions (e.g. a file named 'Integrations' vs the integrations dir); Partial/corrupted prior installs that left a file in the directory position","solutions":["Inspect the offending component printed in the label (e.g. ls -la .specify) and identify what created it","If it is a stray file, delete or rename it, then re-run specify integration install/init","If it is legitimate config, relocate it so the path can be a directory"],"exampleFix":"# before\n-rw-r--r-- .specify        # stray file blocks save()\n# after\nrm .specify && mkdir -p .specify/integrations","handlingStrategy":"validation","validationCode":"def dir_chain_clear(root: Path, directory: Path) -> bool:\n    cur = root\n    for part in directory.relative_to(root).parts:\n        cur = cur / part\n        if cur.exists() and not cur.is_dir():\n            return False\n    return True","typeGuard":null,"tryCatchPattern":"try:\n    manifest.save()\nexcept ValueError as exc:\n    if \"not a directory\" in str(exc):\n        remove_blocking_file_and_retry()\n    else:\n        raise","preventionTips":["Never create files named .specify or integrations in the chain","Check scaffolding tools that might write marker files at those names","Validate the chain before install in CI scripts"],"tags":["manifest","filesystem","integrations"],"backgroundTag":null,"analyzedSha":"bf88c9f9a82fa370c7a7257aa2b3cf10b457b65c","analyzedAt":"2026-08-14T19:43:37.150Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}