HKUDS/Vibe-Trading · error · ValueError

{field_name} cannot be empty

Error message

{field_name} cannot be empty

What it means

normalize_required_text in agent/src/goal/policy.py strips whitespace from a required text field and raises ValueError('{field_name} cannot be empty') when nothing remains. It is the shared sanitizer behind goal/session APIs like replace_goal, update_goal, get_goal, list_criteria and list_claims, so blank or whitespace-only inputs fail fast.

Source

Thrown at agent/src/goal/policy.py:32

)


def normalize_required_text(value: str, field_name: str) -> str:
    """Strip and validate a required text field.

    Args:
        value: User supplied text.
        field_name: Field name for the error message.

    Returns:
        The stripped value.

    Raises:
        ValueError: If the stripped value is empty.
    """
    text = value.strip()
    if not text:
        raise ValueError(f"{field_name} cannot be empty")
    return text


def reject_live_execution_objective(objective: str) -> None:
    """Reject direct live-trading or order-execution goal text.

    Args:
        objective: Research goal objective.

    Raises:
        ValueError: If the objective looks like an execution request.
    """
    text = objective.strip()
    for pattern in _EXECUTION_PATTERNS:
        if pattern.search(text):
            raise ValueError("live trading or execution goals are not supported")

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Pass a non-blank, trimmed string (objective, session_id, criterion text) to the goal API
  2. Validate in the caller/UI before invoking the store: reject empty input with a user-facing message
  3. If the value comes from a template, strip it yourself and provide a sensible default
  4. Check you are not accidentally passing the wrong positional arg (e.g. session_id where objective goes)

Example fix

# before
store.replace_goal(session_id="s1", objective="   ", criteria=["x"])
# after
objective = "Identify momentum factors in US equities".strip()
store.replace_goal(session_id="s1", objective=objective, criteria=["x"])
Defensive patterns

Strategy: validation

Validate before calling

def require_text(value: str, field: str) -> str:
    cleaned = (value or '').strip()
    if not cleaned:
        raise ValueError(f'{field} must be non-blank')
    return cleaned

objective = require_text(user_input, 'goal objective')
session_id = require_text(session_id, 'session_id')
store.replace_goal(session_id=session_id, objective=objective, criteria=[...])

Type guard

def is_non_blank(value: str) -> bool:
    return isinstance(value, str) and bool(value.strip())

Try / catch

try:
    store.replace_goal(session_id=sid, objective=obj, criteria=cs)
except ValueError as e:
    if 'cannot be empty' in str(e):
        # surface a user-facing 'required field' message
        raise UserInputError(str(e)) from e
    raise

Prevention

When it happens

Trigger: Calling any goal API with session_id=' ', objective='', or a criteria/claim text of '' (or '\t'/'\n') — the strip() result is empty and the guard fires.

Common situations: CLI/agent passing an unfiltered user prompt as the goal objective; frontend sending empty strings instead of omitting fields; trailing-newline strings from templates or config; tests that construct goals from blank fixtures.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/3215ba41f652b969. Report an issue: GitHub.