langchain-ai/deepagents · error · ValueError

argv[0] must be a non-empty executable path.

Error message

argv[0] must be a non-empty executable path.

What it means

After checking list contents, `_normalize_argv` verifies that the first argv element is a non-blank string, since `argv[0]` is the executable path passed to process spawning. An argv whose first entry is empty or whitespace-only cannot identify a program, so validation fails.

Source

Thrown at libs/code/deepagents_code/hooks/models/config.py:51

    type: Literal["command"]
    command: str
    argv: list[str] | None = None
    timeout: float | None = Field(default=None, gt=0, allow_inf_nan=False)
    status_message: str | None = Field(default=None, alias="statusMessage")
    async_: bool | None = Field(default=None, alias="async")

    @field_validator("argv", mode="after")
    @classmethod
    def _normalize_argv(cls, value: list[str] | None) -> list[str] | None:
        if value is None:
            return None
        if not value or not all(isinstance(part, str) for part in value):
            msg = "argv must be a non-empty list of strings when provided."
            raise ValueError(msg)
        if not value[0].strip():
            msg = "argv[0] must be a non-empty executable path."
            raise ValueError(msg)
        return value

    @field_validator("async_", mode="after")
    @classmethod
    def _normalize_async(cls, value: bool | None) -> None:
        if value:
            msg = "async command hooks are not yet supported."
            raise ValueError(msg)


# Extension point for future handler kinds, kept as a plain assignment rather
# than a `type` alias: a `type` alias becomes the schema identity and renames
# the generated `$defs` entry from `CommandHandlerSpec` to `HandlerSpec`.
HandlerSpec = CommandHandlerSpec


class MatcherGroup(_ConfigModel):
    """A matcher and its ordered hook handlers."""

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Set `argv[0]` to the actual executable path or name (e.g. `"python"`, `"/usr/local/bin/myhook")`
  2. Check the source of the value (env var, setting, template) and ensure it is populated and trimmed
  3. Use an absolute path if the executable is not on PATH

Example fix

// before
CommandHandlerSpec(argv=[os.environ.get("HOOK_BIN", ""), "run"])
// after
hook_bin = os.environ.get("HOOK_BIN", "/usr/local/bin/myhook").strip()
CommandHandlerSpec(argv=[hook_bin, "run"])
Defensive patterns

Strategy: validation

Validate before calling

if argv and (not isinstance(argv[0], str) or not argv[0].strip()):
    raise ValueError("argv[0] must be a non-empty executable path")

Type guard

def has_executable_head(argv: list[str]) -> bool:
    return bool(argv) and isinstance(argv[0], str) and argv[0].strip() != ""

Try / catch

try:
    spec = CommandHandlerSpec(argv=argv)
except ValueError as e:
    logger.error("bad hook command: %s", e)
    sys.exit(1)

Prevention

When it happens

Trigger: Constructing a `CommandHandlerSpec` with `argv=["", "--flag"]`, `argv=[" "]`, or where the executable string was produced from an empty/whitespace env var or unset setting.

Common situations: Env-var-driven hook commands (`HOOK_CMD=""`) interpolated into argv[0]; template/config rendering that leaves the command slot blank; copy-paste of hook examples with the binary name removed.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/ca535a284f06424a. Report an issue: GitHub.