github/spec-kit · error · IntegrationDescriptorError

Script entry must be a non-empty string

Error message

Script entry must be a non-empty string

What it means

Raised by IntegrationDescriptor._validate() (src/specify_cli/integrations/catalog.py:809) when an element of provides.scripts is not a string or is empty/whitespace-only. Unlike command entries (mappings), script entries are plain relative-path strings, and each must be non-empty before the path-safety check runs.

Source

Thrown at src/specify_cli/integrations/catalog.py:809

                    "Command entry missing 'name' or 'file'"
                )
            cmd_name = cmd["name"]
            cmd_file = cmd["file"]
            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

View on GitHub (pinned to bf88c9f9a8)

Solutions

  1. Make every provides.scripts element a non-empty string path.
  2. Remove null/empty placeholders from the list.
  3. Move any command mappings (name/file) into provides.commands instead.
  4. Re-validate the descriptor.

Example fix

# before
provides:
  scripts:
    - {name: setup, file: setup.sh}

# after
provides:
  scripts:
    - scripts/bash/setup.sh
Defensive patterns

Strategy: type-guard

Validate before calling

def bad_script_entries(scripts):
    return [s for s in scripts if not isinstance(s, str) or not s.strip()]

Type guard

def is_script_entry(v) -> bool:
    return isinstance(v, str) and bool(v.strip())

Prevention

When it happens

Trigger: A descriptor with 'provides: scripts: [null, setup.sh, ""]' or a script entry parsed as a number/mapping; the isinstance/strip check in the for-loop over scripts raises.

Common situations: Mixing command-style mappings into the scripts list; YAML list entries that are empty lines or placeholder nulls; converting a map of script names to paths without unwrapping.

Related errors


AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14). Data as JSON: /api/errors/17cdda16abb3f650. Report an issue: GitHub.