github/spec-kit · error · IntegrationDescriptorError

Command entry 'file' must be a non-empty string

Error message

Command entry 'file' must be a non-empty string

What it means

Raised by IntegrationDescriptor._validate() (src/specify_cli/integrations/catalog.py:800) when a provides.commands entry's 'file' value is not a string or is empty/whitespace-only. The file value points at the command template inside the integration package, so it must be a non-empty string before the path-safety check that follows.

Source

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

                "Integration must provide at least one command or script"
            )
        for cmd in commands:
            if not isinstance(cmd, dict):
                raise IntegrationDescriptorError(
                    "Each command entry must be a mapping"
                )
            if "name" not in cmd or "file" not in cmd:
                raise IntegrationDescriptorError(
                    "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 -----------------------------------------------

View on GitHub (pinned to bf88c9f9a8)

Solutions

  1. Set 'file' to a non-empty relative path string such as 'commands/plan.md'.
  2. Verify the key has a value and the YAML under it is not commented out or mis-indented.
  3. Reload the descriptor to confirm validation passes.

Example fix

# before
- name: plan
  file:

# after
- name: plan
  file: commands/plan.md
Defensive patterns

Strategy: type-guard

Validate before calling

def bad_files(commands):
    return [c for c in commands
            if not isinstance(c.get("file"), str) or not c["file"].strip()]

Type guard

def is_nonempty_file(v) -> bool:
    return isinstance(v, str) and bool(v.strip()) and not v.startswith(("/", "\\"))

Prevention

When it happens

Trigger: A command entry with 'file: null', 'file: ""', or a non-string YAML value; the isinstance/strip guard fails before the relative-path check at catalog.py:804 runs.

Common situations: Commenting out a file path but leaving the key with an empty value; YAML parsing 'file: commands/plan.md # note' with trailing syntax errors producing null; copy-paste that lost the value.

Related errors


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