{"record":{"id":"379702f656c10942","repo":"langchain-ai/deepagents","slug":"operation-id-must-be-a-non-empty-string","errorCode":null,"errorMessage":"operation_id must be a non-empty string.","messagePattern":"operation_id must be a non-empty string\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/offload_api.py","lineNumber":522,"sourceCode":"\n    Args:\n        payload: Decoded request JSON.\n\n    Returns:\n        Operation id, runtime context, and accumulated hook responses.\n\n    Raises:\n        TypeError: If the payload or a structured field has the wrong shape.\n    \"\"\"\n    if not isinstance(payload, dict):\n        msg = \"Offload request must be a JSON object.\"\n        raise TypeError(msg)\n    operation_id = payload.get(\"operation_id\")\n    context = payload.get(\"context\")\n    responses = payload.get(\"hook_responses\", {})\n    if not isinstance(operation_id, str) or not operation_id:\n        msg = \"operation_id must be a non-empty string.\"\n        raise TypeError(msg)\n    if not isinstance(context, dict):\n        msg = \"context must be a JSON object.\"\n        raise TypeError(msg)\n    if not isinstance(responses, dict):\n        msg = \"hook_responses must be a JSON object.\"\n        raise TypeError(msg)\n    validated_context = {str(key): value for key, value in context.items()}\n    _validate_context(validated_context)\n    return (\n        operation_id,\n        _strip_transport_model_params(validated_context),\n        {str(key): value for key, value in responses.items()},\n    )\n\n\ndef _hydrate_state(values: object) -> _OffloadState:\n    \"\"\"Hydrate serialized checkpoint messages for the compaction service.\n","sourceCodeStart":504,"sourceCodeEnd":540,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/offload_api.py#L504-L540","documentation":"Every offload operation is identified by `operation_id`, which must be a non-empty string. The check rejects missing keys, None, empty strings, and non-string values so operations can be tracked and correlated reliably. This fires inside _operation_payload before context validation.","triggerScenarios":"Calling offload() with payload={'context': {...}} (key omitted), {'operation_id': ''}, {'operation_id': None}, {'operation_id': 123}, or {'operation_id': some_uuid.UUID instance}.","commonSituations":"Constructing request dicts by hand and forgetting the id, an upstream generator producing empty ids for skipped events, passing a UUID object instead of its string form, or template/config substitution leaving the field blank.","solutions":["Generate an id if you do not have one: operation_id=str(uuid.uuid4()) (or str(uuid4()) before payload construction).","Cast UUIDs/ids to str(...) at payload-build time.","Add a guard: if not operation_id: raise/skip with a clear log before calling offload().","Fix the upstream producer that emits empty operation ids."],"exampleFix":"// before\npayload = {\"context\": ctx}\n// after\nimport uuid\npayload = {\"operation_id\": str(uuid.uuid4()), \"context\": ctx}","handlingStrategy":"validation","validationCode":"def validate_operation_id(payload):\n    op_id = payload.get(\"operation_id\")\n    if not isinstance(op_id, str) or not op_id:\n        raise ValueError(\"operation_id must be a non-empty string before calling offload\")","typeGuard":"def has_operation_id(payload) -> bool:\n    op_id = payload.get(\"operation_id\") if isinstance(payload, dict) else None\n    return isinstance(op_id, str) and bool(op_id)","tryCatchPattern":"try:\n    state = await offload(thread_id, payload)\nexcept TypeError as exc:\n    if \"operation_id\" in str(exc):\n        import uuid\n        payload[\"operation_id\"] = str(uuid.uuid4())\n        state = await offload(thread_id, payload)\n    else:\n        raise","preventionTips":["Generate operation ids at request-construction time with uuid4","Cast UUID/other id objects to str before embedding","Validate required keys with a payload schema check before dispatch","Trace upstream producers that may emit empty ids for skipped events"],"tags":["type-error","validation","payload","required-field"],"backgroundTag":"missing-required-field","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}