{"record":{"id":"8d951b06d48ff795","repo":"langchain-ai/deepagents","slug":"goal-criteria-request-requires-an-objective","errorCode":null,"errorMessage":"Goal criteria request requires an objective.","messagePattern":"Goal criteria request requires an objective\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/goal_rubric.py","lineNumber":1226,"sourceCode":"    Raises:\n        TypeError: If the request or one of its fields has the wrong type.\n        ValueError: If a required request value is missing or invalid.\n    \"\"\"\n    if not isinstance(value, dict):\n        msg = \"Goal criteria request must be an object.\"\n        raise TypeError(msg)\n    request_id = value.get(\"request_id\")\n    kind = value.get(\"kind\")\n    objective = value.get(\"objective\")\n    if not isinstance(request_id, str) or not request_id.strip():\n        msg = \"Goal criteria request requires a request_id.\"\n        raise ValueError(msg)\n    if kind not in {\"create\", \"amend\"}:\n        msg = \"Goal criteria request kind must be create or amend.\"\n        raise ValueError(msg)\n    if not isinstance(objective, str) or not objective.strip():\n        msg = \"Goal criteria request requires an objective.\"\n        raise ValueError(msg)\n\n    # Values are validated for non-blankness but stored verbatim (not stripped):\n    # this feature deliberately preserves the user's exact goal/criteria wording,\n    # and the prompt builders wrap each value in explicit XML boundaries.\n    optional: dict[str, str] = {}\n    for key in (\"criteria\", \"feedback\", \"previous_criteria\"):\n        item = value.get(key)\n        if item is None:\n            continue\n        if not isinstance(item, str):\n            msg = f\"Goal criteria request field {key} must be text.\"\n            raise TypeError(msg)\n        optional[key] = item\n\n    if kind == \"amend\":\n        criteria = optional.get(\"criteria\", \"\")\n        feedback = optional.get(\"feedback\", \"\")\n        if not criteria.strip() or not feedback.strip():","sourceCodeStart":1208,"sourceCodeEnd":1244,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/goal_rubric.py#L1208-L1244","documentation":"Every goal-criteria request carries the goal `objective`, which must be a non-blank string since it becomes the persisted goal text. `_goal_criteria_request` raises this `ValueError` when `objective` is missing, not a string, or only whitespace. Values are stored verbatim (not stripped) to preserve the user's exact wording.","triggerScenarios":"Dispatching a goal-criteria request where `objective` is absent, `None`, an empty string, whitespace-only, or a non-string (list, dict, number) via the middleware's `before_agent`/`abefore_agent` entry points.","commonSituations":"A UI flow that submits an amend request without the user retyping the objective; templated requests with the objective left as a placeholder; form input that wasn't trimmed and was pure whitespace.","solutions":["Provide a non-empty string in the `objective` field of the request.","For amend requests, re-send the current objective if the caller doesn't change it.","Reject blank user input at the UI/form layer before constructing the request."],"exampleFix":"// before\nrequest = {\"request_id\": rid, \"kind\": \"create\", \"objective\": \"   \"}\n// after\nrequest = {\"request_id\": rid, \"kind\": \"create\", \"objective\": \"Automate release notes generation\"}","handlingStrategy":"validation","validationCode":"objective = value.get(\"objective\")\nif not isinstance(objective, str) or not objective.strip():\n    raise ValueError(\"objective must be a non-blank string\")","typeGuard":"def has_valid_objective(value: dict) -> bool:\n    obj = value.get(\"objective\")\n    return isinstance(obj, str) and bool(obj.strip())","tryCatchPattern":"try:\n    run_middleware(state)\nexcept ValueError as e:\n    if \"requires an objective\" in str(e):\n        prompt_user_for_objective()","preventionTips":["Require the objective in the UI form before enabling submit.","Trim and check `strip()` on user input before constructing the request.","For amend flows, default the objective to the current persisted goal text."],"tags":["validation","valueerror","goal-criteria"],"backgroundTag":"missing-required-field","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}