{"record":{"id":"2eef981067940d33","repo":"langchain-ai/deepagents","slug":"goal-criteria-request-requires-a-request-id","errorCode":null,"errorMessage":"Goal criteria request requires a request_id.","messagePattern":"Goal criteria request requires a request_id\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/goal_rubric.py","lineNumber":1220,"sourceCode":"\n    Returns:\n        A normalized typed request: a `GoalAmendRequest` when `kind` is amend\n        (with `criteria` and `feedback` guaranteed present), otherwise a\n        `GoalCreateRequest`. Fields not valid for the resolved kind are dropped.\n\n    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)","sourceCodeStart":1202,"sourceCodeEnd":1238,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/goal_rubric.py#L1202-L1238","documentation":"The goal-criteria middleware validates every incoming goal-criteria request dict before acting on it. The `request_id` field is required and must be a non-blank string, because it is used to correlate the proposal with the caller's turn. `_goal_criteria_request` raises this `ValueError` when the key is absent, not a string, or only whitespace.","triggerScenarios":"Calling the middleware hook path (`before_agent`/`abefore_agent`) with a state payload whose goal-criteria request dict lacks `request_id`, sets it to `None`/`\"\"`/`\"   \"`, or sets it to a non-string like an int or dict.","commonSituations":"Hand-crafted or older persisted state that predates the `request_id` field; a client building the request dict manually and forgetting the key; deserialized JSON where the id was serialized as a number.","solutions":["Add a `request_id` key with a non-empty string value (e.g. a uuid4 string) to the request dict.","Coerce non-string ids with `str(value)` before dispatching the request.","Check the state for a stale goal-criteria request written by an older version and clear it or upgrade its shape."],"exampleFix":"// before\nrequest = {\"kind\": \"create\", \"objective\": \"Ship feature\"}\n// after\nimport uuid\nrequest = {\"request_id\": str(uuid.uuid4()), \"kind\": \"create\", \"objective\": \"Ship feature\"}","handlingStrategy":"validation","validationCode":"request_id = value.get(\"request_id\")\nif not isinstance(request_id, str) or not request_id.strip():\n    raise ValueError(\"goal criteria request needs a non-blank string request_id\")","typeGuard":"def has_valid_request_id(value: dict) -> bool:\n    rid = value.get(\"request_id\")\n    return isinstance(rid, str) and bool(rid.strip())","tryCatchPattern":"try:\n    run_middleware(state)\nexcept ValueError as e:\n    if \"requires a request_id\" in str(e):\n        state[\"goal_request\"][\"request_id\"] = str(uuid.uuid4())\n        run_middleware(state)","preventionTips":["Always generate a `request_id` via `uuid.uuid4()` when building goal-criteria requests.","Use a single shared request-builder function so the field cannot be forgotten.","Validate the full request shape in tests that exercise the middleware."],"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"}