github/spec-kit · error · ValueError
Absolute paths are not allowed in manifests: {rel}
Error message
Absolute paths are not allowed in manifests: {rel} What it means
Raised by _validate_rel_path() in manifest.py (src/specify_cli/integrations/manifest.py:36) when a manifest operation is given a relative path that is actually absolute. Manifests record every installed file as a path relative to the project root (hashed and removed on uninstall), so absolute paths — which could target anything on disk — are rejected before any filesystem write.
Source
Thrown at src/specify_cli/integrations/manifest.py:36
def _sha256(path: Path) -> str:
"""Return the hex SHA-256 digest of *path*."""
h = hashlib.sha256()
with open(path, "rb") as fh:
for chunk in iter(lambda: fh.read(8192), b""):
h.update(chunk)
return h.hexdigest()
def _validate_rel_path(rel: Path, root: Path) -> Path:
"""Resolve *rel* against *root* and verify it stays within *root*.
Raises ``ValueError`` if *rel* is absolute, contains ``..`` segments
that escape *root*, or otherwise resolves outside the project root.
"""
if rel.is_absolute():
raise ValueError(
f"Absolute paths are not allowed in manifests: {rel}"
)
resolved = (root / rel).resolve()
root_resolved = root.resolve()
try:
resolved.relative_to(root_resolved)
except ValueError:
raise ValueError(
f"Path {rel} resolves to {resolved} which is outside "
f"the project root {root_resolved}"
) from None
return resolved
def _manifest_path_label(root: Path, path: Path) -> str:
try:
return path.relative_to(root).as_posix()
except ValueError:View on GitHub (pinned to bf88c9f9a8)
Solutions
- Convert the path to be relative to project_root before recording: path.relative_to(project_root).
- In custom setup() implementations, record the destination relative path ('folder/commands/plan.md'), never the resolved absolute one.
- Check for accidental leading '/' or drive letters in path construction.
Example fix
# before created = dest / "plan.md" # absolute manifest.record_file(str(created), content) # after rel = created.relative_to(project_root) manifest.record_file(rel.as_posix(), content)
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
def to_manifest_rel(path: Path, root: Path) -> Path:
if path.is_absolute():
return path.relative_to(root) # raises if outside root
return path
rel = to_manifest_rel(created_file, project_root)
manifest.record_file(rel.as_posix(), content) Type guard
def is_relative_path(p) -> bool:
return not Path(p).is_absolute() and ".." not in Path(p).parts Try / catch
try:
manifest.record_file(rel_str, content)
except ValueError as e:
if "Absolute paths" in str(e):
rel_str = Path(rel_str).relative_to(project_root).as_posix()
manifest.record_file(rel_str, content)
else:
raise Prevention
- Always pass project-relative POSIX paths to manifest.record_file/record_existing.
- In custom setup() code, derive the relative path via created.relative_to(project_root).
- Never feed resolved/absolute destination paths into the manifest.
When it happens
Trigger: Calling manifest.record_file()/record_existing() (or any code path reaching _validate_rel_path) with a Path like Path('/etc/passwd') or an absolute Windows path 'C:\\x\\y' — rel.is_absolute() is true and ValueError is raised immediately.
Common situations: Custom integration setup() code building file paths from absolute sources (resolved template paths) and passing them straight to manifest.record_file(); passing dest-resolved paths instead of project-relative ones; Windows callers using rooted paths.
Related errors
- Refusing to write event config through a symlink: {walked}
- Invalid command 'file' {label}: {reason}
- Invalid alias {alias!r} for command '{cmd['name']}': {alias_
- Invalid {singular} 'file' {label}: {reason}
- Command entry 'file' must be a relative path without '..': {
AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14).
Data as JSON: /api/errors/2f6e03b8e9c612ca.
Report an issue: GitHub.