github/spec-kit · error · ValueError
Refusing to scaffold outside the repository root: {target}
Error message
Refusing to scaffold outside the repository root: {target} What it means
Raised by _assert_safe_scaffold_target in integration_scaffold.py when the scaffold target file cannot be expressed as a relative path under project_root (Path.relative_to raises ValueError). This is the first of two 'outside the repository root' guards: it catches targets that are not lexically under the supplied root before any symlink resolution happens. The scaffold command refuses to write integration/test skeletons anywhere but inside the Spec Kit source tree.
Source
Thrown at src/specify_cli/integration_scaffold.py:183
project_root / "src" / "specify_cli" / "integrations" / "__init__.py"
).is_file(),
(project_root / "tests" / "integrations").is_dir(),
)
)
def _assert_safe_scaffold_target(project_root: Path, target: Path) -> None:
"""Refuse to scaffold through a symlinked path that could escape the repo.
Walks each component of *target* under *project_root* and rejects any
existing symlinked directory (or symlinked target), then confirms the
write destination still resolves inside the repository root. Mirrors the
symlink-aware guarding used for integration manifests.
"""
try:
rel = target.relative_to(project_root)
except ValueError:
raise ValueError(
f"Refusing to scaffold outside the repository root: {target}"
) from None
current = project_root
for part in rel.parts:
current = current / part
if current.is_symlink():
label = current.relative_to(project_root).as_posix()
raise ValueError(f"Refusing to scaffold through symlinked path: {label}")
root_resolved = project_root.resolve()
try:
target.parent.resolve().relative_to(root_resolved)
except (OSError, ValueError):
raise ValueError(
f"Refusing to scaffold outside the repository root: {target}"
) from None
View on GitHub (pinned to bf88c9f9a8)
Solutions
- Run the scaffold command from the actual Spec Kit repository root so project_root is the parent of src/specify_cli and tests/integrations.
- Pass project_root as the repo root (the directory containing src/specify_cli) rather than a subdirectory or a symlinked alias.
- If the checkout is symlinked, cd into the real (resolved) path or resolve project_root with Path.resolve() before calling scaffold_integration.
Example fix
# before
scaffold_integration(Path("~/repos/spec-kit-link").expanduser(), "my-agent", "markdown")
# after (use the real repo root)
root = Path("~/repos/spec-kit").expanduser().resolve()
scaffold_integration(root, "my-agent", "markdown") Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
def safe_scaffold_target(project_root: Path, target: Path) -> bool:
try:
target.relative_to(project_root)
except ValueError:
return False
return True
# before calling scaffold_integration:
root = root.resolve()
assert safe_scaffold_target(root, root / "src" / "specify_cli" / "integrations" / pkg) Try / catch
try:
scaffold_integration(root, key, itype)
except ValueError as exc:
if "outside the repository root" in str(exc):
root = Path.cwd().resolve() # re-anchor and retry once
else:
raise Prevention
- Always derive project_root with Path.resolve() before scaffolding.
- Run scaffold commands from the repository root rather than passing constructed absolute paths.
- In wrappers, assert target.relative_to(root) succeeds before invoking the API.
When it happens
Trigger: Calling scaffold_integration(project_root, key, type) with a target like project_root/'src'/'specify_cli'/'integrations'/pkg/'__init__.py' when project_root is not an ancestor of target: e.g. project_root was resolved to a different path (symlinked checkout), target was built from an absolute path from another tree, or the caller passed the wrong root.
Common situations: Running the scaffold CLI from a subdirectory so cwd-derived project_root disagrees with the target layout; a symlinked repo checkout where the naive root and the real root differ; CI checking out to a temp path while reusing cached absolute paths.
Related errors
- specify event ${{command}} (${{event}}) failed: ${{(e as Err
- errors.join('; ')
- Error: --number requires a value
- ERROR: Unknown option '{arg}'. Use --help for usage informat
- Refusing to scaffold through symlinked path: {label}
AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14).
Data as JSON: /api/errors/774cf2f1f76c9358.
Report an issue: GitHub.