langchain-ai/deepagents · error · ValueError

choice has a blank 'value': {choice!r}

Error message

choice has a blank 'value': {choice!r}

What it means

`_validate_choice` raises ValueError when a Choice's `value` key is empty or whitespace-only. The `value` is the machine-readable answer returned to the agent, so it must be non-blank; the optional `label` is what the user sees.

Source

Thrown at libs/code/deepagents_code/_ask_user_types.py:213

    itself, so `TypeAdapter(Choice)` does not apply it.

    Callers must pass a parsed `Choice`. A missing `value` never reaches here —
    it is a required key, so pydantic rejects it as `choices.N.value: Field
    required` before the choice-level validators run. On a raw dict this would
    raise `KeyError`, which is not a `ValidationError` and would halt the run.

    Args:
        choice: The parsed `Choice` to check.

    Returns:
        The same `choice`, unchanged.

    Raises:
        ValueError: If `value` is blank or whitespace-only.
    """
    if not choice["value"].strip():
        msg = f"choice has a blank 'value': {choice!r}"
        raise ValueError(msg)
    return choice


class Choice(TypedDict):
    """A single choice option for a multiple choice or multi-select question."""

    value: Annotated[
        str,
        Field(
            description=(
                "The display label for this choice. Also the text returned as "
                "the answer when this choice is selected. A 'multi_select' answer "
                "is a JSON array, so a value may contain commas, quotes, and "
                "newlines; JSON escaping keeps it exact. A 'multiple_choice' "
                "value is returned on its own with no escaping, so keep that "
                "one to a single line."
            )
        ),

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Give every choice a non-empty, distinct `value` string (e.g. "yes", "postgres")
  2. Put the human-friendly wording in `label` and keep `value` as a short identifier
  3. Sanitize generated choices by filtering out entries whose value strips to empty before submitting the question
  4. If values derive from user data, trim and de-duplicate them before building the Choice

Example fix

# before
{"value": "", "label": "PostgreSQL"}
# after
{"value": "postgres", "label": "PostgreSQL"}
Defensive patterns

Strategy: validation

Validate before calling

for c in choices:
    if not c.get("value", "").strip():
        raise ValueError(f"choice has a blank 'value': {c!r}")

Type guard

def is_valid_choice(c: dict) -> bool:
    return isinstance(c.get("value"), str) and bool(c["value"].strip())

Try / catch

try:
    ask_user(questions=questions)
except ValueError as exc:
    if "blank 'value'" in str(exc):
        # regenerate or filter choices before retrying
        ...
    else:
        raise

Prevention

When it happens

Trigger: An ask_user question containing a choice like `{"value": "", "label": "Yes"}` or `{"value": " "}` — validation runs in `_validate_choice` at libs/code/deepagents_code/_ask_user_types.py:213.

Common situations: An LLM emitting choices with placeholder/empty values; code that strips display labels but forgets values; generating choices from a source list containing empty strings; copying a choice template without filling `value`.

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/0c635d61801917dd. Report an issue: GitHub.