{"record":{"id":"81bd40ee9b973dcd","repo":"langchain-ai/deepagents","slug":"the-server-criteria-agent-returned-no-complete-pro","errorCode":null,"errorMessage":"The server criteria agent returned no complete proposal.","messagePattern":"The server criteria agent returned no complete proposal\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/goal_rubric.py","lineNumber":1441,"sourceCode":"        Returns:\n            State updates that persist the proposal and end the parent run.\n\n        Raises:\n            RuntimeError: If the nested agent returned no complete proposal.\n            GoalStateSizeError: If the objective and criteria that will actually\n                be applied exceed the combined notice budget.\n        \"\"\"\n        proposal = _proposal_from_result(result)\n        if proposal is None:\n            # Log the raw nested output so repeated failures are diagnosable —\n            # the RuntimeError message alone cannot say whether the model emitted\n            # empty criteria, near-miss JSON, or prose.\n            logger.warning(\n                \"Criteria agent returned no complete proposal; raw result: %s\",\n                _summarize_criteria_result(result),\n            )\n            msg = \"The server criteria agent returned no complete proposal.\"\n            raise RuntimeError(msg)\n        proposed_objective, criteria = proposal\n        objective = (\n            request[\"objective\"] if request[\"kind\"] == \"create\" else proposed_objective\n        )\n        # `GoalProposal._fit_notice_budget` validated the objective the model\n        # echoed back, but a `create` applies the user's original. The model is\n        # told to preserve it verbatim and nothing enforces that. A paraphrase can\n        # therefore fit the limit while the applied pair exceeds it. Validate what\n        # is actually applied.\n        try:\n            validate_goal_application(objective, criteria)\n        except GoalStateSizeError:\n            # The raised message names only the combined total, which is opaque\n            # to a user who typed an objective and never saw the criteria. Log\n            # the parts so the split is recoverable from the logs.\n            logger.warning(\n                \"Applied goal proposal exceeds the combined budget: objective \"\n                \"%d chars (model proposed %d), criteria %d chars\",","sourceCodeStart":1423,"sourceCodeEnd":1459,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/goal_rubric.py#L1423-L1459","documentation":"During a goal-criteria update, a server-side LLM agent proposes the objective and criteria. `_update` parses the agent's result and, if no well-formed proposal can be extracted (empty criteria, near-miss JSON, or plain prose instead of the expected structure), it logs the raw result and raises this `RuntimeError`.","triggerScenarios":"The criteria agent's model returns malformed output: prose instead of the structured proposal, truncated JSON, an empty response, or a response missing the criteria — typically on weak/fast models, long inputs near the char limits, or rate-limit-degraded responses.","commonSituations":"Non-deterministic model failures during `/goal` create/amend flows; misconfigured criteria-agent model (unreliable provider, low-quality fallback model); network issues causing partial responses that the retry layer surfaced as garbage.","solutions":["Retry the goal create/amend command — model output is non-deterministic and a retry usually yields a parseable proposal.","Check the warning log line (`Criteria agent returned no complete proposal; raw result: ...`) to see what the model actually returned.","Switch the criteria-agent to a stronger model configuration.","Shorten the objective/criteria input (limits are 8000/12000 chars) to reduce truncation risk."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"import json\ndef looks_parseable(raw) -> bool:\n    if not isinstance(raw, str) or not raw.strip():\n        return False\n    try:\n        parsed = json.loads(raw)\n    except (json.JSONDecodeError, TypeError):\n        return False\n    return isinstance(parsed, dict) and bool(parsed.get(\"criteria\"))","typeGuard":"def is_complete_proposal(proposal) -> bool:\n    return (\n        isinstance(proposal, tuple)\n        and len(proposal) == 2\n        and all(isinstance(part, str) and part.strip() for part in proposal)\n    )","tryCatchPattern":"from deepagents_code.goal_rubric import RuntimeError  # raised where?\ntry:\n    apply_goal_rubric(request)\nexcept RuntimeError as e:\n    if \"no complete proposal\" in str(e):\n        log.warning(\"criteria agent returned unparseable output, retrying\")\n        apply_goal_rubric(request)  # model output is non-deterministic","preventionTips":["Configure a strong, reliable model for the criteria agent.","Keep objective/criteria inputs well under the char limits to reduce truncation.","Check the logged raw result (`Criteria agent returned no complete proposal; raw result: ...`) when diagnosing.","Retry once automatically before surfacing the failure to the user."],"tags":["llm","parsing","runtime-error","goal-criteria"],"backgroundTag":"llm-output-parse-failure","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}