{"record":{"id":"0a76ea3f54ec324e","repo":"langchain-ai/deepagents","slug":"offload-result-field-field-r-must-be-an-integer","errorCode":null,"errorMessage":"Offload result field {field!r} must be an integer, got {type(value).__name__}.","messagePattern":"Offload result field (.+?) must be an integer, got (.+?)\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/client/remote_client.py","lineNumber":147,"sourceCode":"        RuntimeError: If a required field is missing or has the wrong type.\n    \"\"\"\n    if not isinstance(result, dict):\n        msg = \"Offload server completed without a typed result.\"\n        raise RuntimeError(msg)  # noqa: TRY004  # protocol fault, not a type misuse\n    status = result.get(\"status\")\n    if not isinstance(status, str) or not status:\n        msg = \"Offload result has no status.\"\n        raise RuntimeError(msg)\n    # Statistics are only meaningful (and only read) for a committed compaction.\n    if status == \"compacted\":\n        for field in _OFFLOAD_RESULT_INT_FIELDS:\n            value = result.get(field)\n            if not isinstance(value, int) or isinstance(value, bool):\n                msg = (\n                    f\"Offload result field {field!r} must be an integer, got \"\n                    f\"{type(value).__name__}.\"\n                )\n                raise RuntimeError(msg)  # noqa: TRY004  # protocol fault\n    return cast(\"OffloadResult\", result)\n\n\ndef _require_thread_id(config: Mapping[str, Any] | None) -> str:\n    \"\"\"Extract and validate that `thread_id` is present in config.\n\n    Args:\n        config: Config dict with `configurable.thread_id`.\n\n    Returns:\n        The thread ID string.\n\n    Raises:\n        ValueError: If `thread_id` is missing.\n    \"\"\"\n    thread_id = (config or {}).get(\"configurable\", {}).get(\"thread_id\")\n    if not thread_id:\n        msg = \"thread_id is required in config.configurable\"","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/client/remote_client.py#L129-L165","documentation":"For a `compacted` offload result, `_validated_offload_result` iterates `_OFFLOAD_RESULT_INT_FIELDS` and requires each statistic field to be an `int` (excluding `bool`, which is an `int` subclass in Python). A wrong-typed value raises `RuntimeError` naming the field and actual type, keeping `OffloadResult` statistics trustworthy.","triggerScenarios":"Server returns `status == \"compacted\"` but a statistics field (e.g. token/message counts in `_OFFLOAD_RESULT_INT_FIELDS`) is a string, float, `null`, or `true`/`false` instead of an integer.","commonSituations":"JSON serialization emitting counts as strings; server-side rewrite of stats using floats; schema drift between client and server versions; `null` for unknown counts.","solutions":["Fix the server to emit statistics as JSON integers, or upgrade client/server to matching schema versions.","Confirm the offending field name from the error message and inspect the server code computing it.","If counts may legitimately be absent, decide whether to default them client-side (requires schema change) rather than sending null.","Retry the compaction after the fix."],"exampleFix":"// before: string counts\nreturn {\"status\": \"compacted\", \"total_tokens\": \"1234\"}\n// after: integer counts\nreturn {\"status\": \"compacted\", \"total_tokens\": 1234}","handlingStrategy":"validation","validationCode":"INT_FIELDS = (\"total_tokens\",)  # mirror _OFFLOAD_RESULT_INT_FIELDS\ndef stats_are_ints(result: dict) -> bool:\n    return result.get(\"status\") == \"compacted\" and all(\n        isinstance(result.get(f), int) and not isinstance(result.get(f), bool)\n        for f in INT_FIELDS\n    )\nif not stats_are_ints(raw): fix_server_serialization()","typeGuard":"def valid_stats(result: dict, fields: tuple[str, ...]) -> TypeGuard[dict]:\n    return all(\n        isinstance(result.get(f), int) and not isinstance(result.get(f), bool)\n        for f in fields\n    )","tryCatchPattern":"try:\n    result = await aoffload(...)\nexcept RuntimeError as exc:\n    if \"must be an integer\" in str(exc):\n        fix_field_type(exc)  # field name and actual type are in the message","preventionTips":["Serialize statistics as JSON integers, never strings, floats, or booleans","Emit an agreed default instead of null when a count is unknown","Add schema/contract tests covering all `_OFFLOAD_RESULT_INT_FIELDS`"],"tags":["offload","protocol","validation","types"],"backgroundTag":"invalid-server-response","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}