langchain-ai/deepagents · error · ValueError

must contain non-whitespace text

Error message

must contain non-whitespace text

What it means

`_require_nonempty_text` is a Pydantic validator for goal-rubric fields that rejects values consisting only of whitespace, raising `ValueError('must contain non-whitespace text')`. Goal proposals (objective/criteria text) must carry real content so the rubric evaluator receives meaningful text.

Source

Thrown at libs/code/deepagents_code/goal_rubric.py:212

            max_length=RUBRIC_CHAR_LIMIT,
            description="A concise flat Markdown bullet list of acceptance criteria.",
        ),
    ]

    @field_validator("objective", "criteria")
    @classmethod
    def _require_nonempty_text(cls, value: str) -> str:
        """Reject whitespace-only structured output so the model can retry.

        Returns:
            The original nonempty text.

        Raises:
            ValueError: If `value` contains only whitespace.
        """
        if not value.strip():
            msg = "must contain non-whitespace text"
            raise ValueError(msg)
        return value

    @model_validator(mode="after")
    def _fit_notice_budget(self) -> Self:
        """Reject a proposal whose objective and criteria exceed the budget.

        Returns:
            The original proposal when it fits.

        Raises:
            GoalStateSizeError: If the combined text exceeds the notice budget.
                pydantic wraps a `ValueError` raised inside a `model_validator`,
                so a caller constructing a `GoalProposal` directly observes a
                `ValidationError` carrying this message, never this type. Inside
                an agent, `_raise_terminal_goal_state_size_error` unwraps it back
                to this type and ends the turn rather than retrying, because the
                combined budget is deterministic and half of it is the user's
                objective. The direct `validate_goal_application` calls raise it

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Ensure the field value is trimmed, non-empty text before constructing the model
  2. Check the upstream producer (e.g. LLM response) and re-prompt or fail fast when it returns empty/whitespace text
  3. Handle the `ValueError` at the boundary and surface which field was empty

Example fix

// before
rubric = GoalRubric(objective="   ", criteria=["tests pass"])

// after
objective = raw_objective.strip()
if not objective:
    raise ValueError("objective must contain non-whitespace text")
rubric = GoalRubric(objective=objective, criteria=["tests pass"])
Defensive patterns

Strategy: validation

Validate before calling

def ensure_text(v: str, field: str) -> str:
    v = (v or "").strip()
    if not v:
        raise ValueError(f"{field} must contain non-whitespace text")
    return v

Type guard

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

Try / catch

try:
    rubric = GoalRubric(objective=raw, criteria=items)
except ValueError as exc:
    logger.error("invalid goal text: %s", exc)

Prevention

When it happens

Trigger: Constructing or validating a goal-rubric model with a field set to `''`, `' '`, `'\n\t'`, or a value stripped to empty — e.g. an LLM produced an empty objective string that was passed straight into the model.

Common situations: Model outputs truncated to whitespace; templates with unfilled placeholders that collapse to empty; upstream code doing `.get("objective", "")` defaulting to empty string; whitespace-only joins of criteria lists.

Related errors


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