langchain-ai/deepagents · error · ValueError

argv must be a non-empty list of strings when provided.

Error message

argv must be a non-empty list of strings when provided.

What it means

`_normalize_argv` is a pydantic field validator on the command hook handler spec in `libs/code/deepagents_code/hooks/models/config.py`. It rejects any `argv` that is provided but is either an empty list or contains non-string elements. The library requires a well-formed command vector so it can spawn the hook process safely.

Source

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

    `argv` is a temporary legacy-migration compatibility field. Remove it with
    `hooks.legacy` and `hooks.migration` after September 1, 2026.
    """

    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

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Ensure every element of `argv` is a string, coercing numbers/paths with `str(...)` before assignment
  2. Provide at least one element — put the executable path in `argv[0]`
  3. If the hook should have no command, omit the `argv` key (or pass None) instead of `[]`

Example fix

// before
handler = CommandHandlerSpec(argv=["python", 3])
// after
handler = CommandHandlerSpec(argv=["python", "-m", "mypkg.hooks"])
Defensive patterns

Strategy: validation

Validate before calling

def valid_argv(argv):
    return argv is None or (isinstance(argv, list) and len(argv) > 0 and all(isinstance(p, str) for p in argv))

if not valid_argv(cfg.get("argv")):
    raise ValueError("argv must be a non-empty list of strings")

Type guard

def is_str_list(v: object) -> TypeGuard[list[str]]:
    return isinstance(v, list) and all(isinstance(x, str) for x in v)

Try / catch

try:
    spec = CommandHandlerSpec(**cfg)
except ValueError as e:
    logger.error("invalid hook config: %s", e)
    raise SystemExit(1) from e

Prevention

When it happens

Trigger: Defining a command hook in hook config where `argv` is explicitly given as `[]`, or as a list containing non-strings (e.g. `["echo", 42]`, `[None]`, or nested lists), when the config model is validated by pydantic.

Common situations: Hand-edited hook config files (JSON/TOML/YAML) where numbers or booleans sneak into argv; programmatic config construction that passes an empty list as a placeholder; deserializing config where argv items were parsed as ints.

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/07b42275a74e65f1. Report an issue: GitHub.