github/spec-kit · error · ValueError
Integration manifest directory path is not a directory: {lab
Error message
Integration manifest directory path is not a directory: {label} What it means
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.
Source
Thrown at src/specify_cli/integrations/manifest.py:75
def _ensure_safe_manifest_directory(root: Path, directory: Path) -> None:
"""Create a manifest directory without following symlinked parents."""
root_resolved = root.resolve()
try:
rel = directory.relative_to(root)
except ValueError:
label = _manifest_path_label(root, directory)
raise ValueError(f"Integration manifest directory escapes project root: {label}") from None
current = root
for part in rel.parts:
current = current / part
label = _manifest_path_label(root, current)
if current.is_symlink():
raise ValueError(f"Refusing to use symlinked integration manifest directory: {label}")
if current.exists():
if not current.is_dir():
raise ValueError(f"Integration manifest directory path is not a directory: {label}")
try:
current.resolve().relative_to(root_resolved)
except (OSError, ValueError):
raise ValueError(f"Integration manifest directory escapes project root: {label}") from None
continue
current.mkdir()
try:
current.resolve().relative_to(root_resolved)
except (OSError, ValueError):
raise ValueError(f"Integration manifest directory escapes project root: {label}") from None
def _ensure_safe_manifest_destination(root: Path, path: Path) -> None:
"""Refuse manifest writes that would escape the project or follow symlinks."""
root_resolved = root.resolve()
_ensure_safe_manifest_directory(root, path.parent)
label = _manifest_path_label(root, path)
if path.is_symlink():View on GitHub (pinned to bf88c9f9a8)
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
Example fix
# before -rw-r--r-- .specify # stray file blocks save() # after rm .specify && mkdir -p .specify/integrations
Defensive patterns
Strategy: validation
Validate before calling
def dir_chain_clear(root: Path, directory: Path) -> bool:
cur = root
for part in directory.relative_to(root).parts:
cur = cur / part
if cur.exists() and not cur.is_dir():
return False
return True Try / catch
try:
manifest.save()
except ValueError as exc:
if "not a directory" in str(exc):
remove_blocking_file_and_retry()
else:
raise Prevention
- 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
When it happens
Trigger: 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).
Common situations: 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
Related errors
- Integration manifest path is not a file: {label}
- No bundle.yml found in '{bundle_dir}'.
- No bundle.yml found in '{candidate}'.
- No bundle.yml found at '{target}'.
- No extension.yml found in {source_path}
AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14).
Data as JSON: /api/errors/341406c29ec513ef.
Report an issue: GitHub.