langchain-ai/deepagents · error · ValueError

Classifier result did not contain exactly one decision per r

Error message

Classifier result did not contain exactly one decision per reviewed call

What it means

When Auto Mode delegates review of a batch of gated tool calls to a classifier, the classifier must return exactly one decision per reviewed call, with no missing, duplicated, or unknown tool_call_ids. `_validate_classifier_ids` (called from `awrap_model_call`) enforces this by comparing the decision ids against the expected id set. Any mismatch means the classifier output is unusable, so the middleware fails fast with this ValueError.

Source

Thrown at libs/code/deepagents_code/auto_mode.py:2101

        if isinstance(value, str) and value:
            return value
    return type(model).__name__


def _validate_classifier_ids(batch: AutoDecisionBatch, expected_ids: set[str]) -> None:
    """Validate exact one-to-one classifier coverage.

    Args:
        batch: Structured classifier result.
        expected_ids: Tool-call IDs requiring model review.

    Raises:
        ValueError: If IDs are missing, duplicated, or unknown.
    """
    actual_ids = [decision.tool_call_id for decision in batch.decisions]
    if len(actual_ids) != len(set(actual_ids)) or set(actual_ids) != expected_ids:
        msg = "Classifier result did not contain exactly one decision per reviewed call"
        raise ValueError(msg)


class AutoModeHITLMiddleware(HumanInTheLoopMiddleware[AutoModeState, Any, Any]):
    """Apply deterministic policy, classifier review, and HITL fallback."""

    trace_policy = TracePolicy(process_inputs=omit_payload)
    """Omit hook inputs from traces by default; set a `TracePolicy` to override."""

    state_schema = AutoModeState

    @property
    def name(self) -> str:
        """Replace the stock main-agent HITL middleware by name."""
        return "HumanInTheLoopMiddleware"

    def __init__(
        self,
        interrupt_on: Mapping[str, bool | InterruptOnConfig],

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Use a structured-output-capable classifier model or stricter response schema so every reviewed tool_call_id gets exactly one decision.
  2. Retry the classifier with a prompt that emphasizes returning one decision per call id, verbatim from the request.
  3. For long batches, split review into smaller chunks so the classifier cannot truncate decisions.
  4. Log the classifier's raw output to identify which ids were missing, duplicated, or unknown.

Example fix

// before
classifier_response = '{"decisions": [{"tool_call_id": "call_1", "decision": "approve"}]}'  // call_2 missing
// after
classifier_response = '{"decisions": [{"tool_call_id": "call_1", "decision": "approve"}, {"tool_call_id": "call_2", "decision": "reject"}]}'
Defensive patterns

Strategy: validation

Validate before calling

expected = {c['id'] for c in batch.tool_calls}
actual = [d.tool_call_id for d in batch.decisions]
if len(actual) != len(set(actual)) or set(actual) != expected:
    # retry the classifier before consuming results
    batch = rerun_classifier(batch.tool_calls)

Type guard

def classifier_batch_is_complete(decisions: list[Decision], expected_ids: set[str]) -> bool:
    ids = [d.tool_call_id for d in decisions]
    return len(ids) == len(set(ids)) and set(ids) == expected_ids

Try / catch

try:
    validated = middleware_validate(batch)
except ValueError as e:
    if 'exactly one decision per reviewed call' in str(e):
        batch = retry_classifier_with_stricter_prompt(batch)  # or fall back to HITL review
    else:
        raise

Prevention

When it happens

Trigger: The classifier model returns a batch whose decisions contain: a tool_call_id not in the reviewed batch, a duplicated id (len(actual_ids) != len(set(actual_ids))), or omits an id present in the batch — typically because the classifier LLM truncated, hallucinated, or reformatted ids.

Common situations: A weak/small classifier model emitting free-text instead of the expected structured decisions; prompt changes that drop the tool_call_id field; long batches where the model truncates output; classifier response parsing that mangles ids.

Related errors


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