github/spec-kit · error · IntegrationDescriptorError
Script entry must be a relative path without '..': {script_e
Error message
Script entry must be a relative path without '..': {script_entry} What it means
Raised by IntegrationDescriptor._validate() (src/specify_cli/integrations/catalog.py:813) when a provides.scripts entry is an absolute path, contains '..', or carries a drive/anchor component. Scripts are resolved inside the integration package, so only simple relative paths are accepted; the offending script_entry appears in the message.
Source
Thrown at src/specify_cli/integrations/catalog.py:813
if not isinstance(cmd_name, str) or not cmd_name.strip():
raise IntegrationDescriptorError(
"Command entry 'name' must be a non-empty string"
)
if not isinstance(cmd_file, str) or not cmd_file.strip():
raise IntegrationDescriptorError(
"Command entry 'file' must be a non-empty string"
)
if os.path.isabs(cmd_file) or ".." in Path(cmd_file).parts or Path(cmd_file).drive or Path(cmd_file).anchor:
raise IntegrationDescriptorError(
f"Command entry 'file' must be a relative path without '..': {cmd_file}"
)
for script_entry in scripts:
if not isinstance(script_entry, str) or not script_entry.strip():
raise IntegrationDescriptorError(
"Script entry must be a non-empty string"
)
if os.path.isabs(script_entry) or ".." in Path(script_entry).parts or Path(script_entry).drive or Path(script_entry).anchor:
raise IntegrationDescriptorError(
f"Script entry must be a relative path without '..': {script_entry}"
)
# -- Property accessors -----------------------------------------------
@property
def id(self) -> str:
return self.data["integration"]["id"]
@property
def name(self) -> str:
return self.data["integration"]["name"]
@property
def version(self) -> str:
return self.data["integration"]["version"]
@propertyView on GitHub (pinned to bf88c9f9a8)
Solutions
- Vendor the script into the integration package and reference it with a plain relative path.
- Strip leading slashes, drive letters, and '..' segments from the entry.
- Re-validate the descriptor.
Example fix
# before
provides:
scripts:
- /opt/shared/setup.sh
# after
provides:
scripts:
- scripts/bash/setup.sh Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
def unsafe_scripts(scripts):
return [s for s in scripts
if Path(s).is_absolute() or ".." in Path(s).parts
or Path(s).drive or Path(s).anchor] Type guard
def is_safe_script_path(s: str) -> bool:
p = Path(s)
return not p.is_absolute() and ".." not in p.parts and not p.drive and not p.anchor Prevention
- Vendor shared scripts into the integration package instead of absolute references.
- Run a path-safety lint on descriptor entries in CI.
- Avoid '..' and drive-letter paths anywhere in provides.
When it happens
Trigger: 'provides: scripts: [/usr/local/bin/setup.sh]' or 'scripts: [../../lib/setup.sh]'; the combined isabs/'..'/drive/anchor check raises with the concrete path.
Common situations: Pointing at a system-wide script installed elsewhere on the machine; referencing a shared scripts directory outside the integration; Windows drive-letter paths copied into the descriptor.
Related errors
- Command entry 'file' must be a relative path without '..': {
- Output path {candidate!r} escapes directory {base!r}
- Invalid command name {cmd_name!r}: {name_reason}
- Invalid command alias {alias!r}: {alias_reason}
- Invalid Copilot prompt name {cmd_name!r}: {name_reason}
AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14).
Data as JSON: /api/errors/4a54c5c364c7f566.
Report an issue: GitHub.