langchain-ai/deepagents · error · RuntimeError

Offload result field {field!r} must be an integer, got {type

Error message

Offload result field {field!r} must be an integer, got {type(value).__name__}.

What it means

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.

Source

Thrown at libs/code/deepagents_code/client/remote_client.py:147

        RuntimeError: If a required field is missing or has the wrong type.
    """
    if not isinstance(result, dict):
        msg = "Offload server completed without a typed result."
        raise RuntimeError(msg)  # noqa: TRY004  # protocol fault, not a type misuse
    status = result.get("status")
    if not isinstance(status, str) or not status:
        msg = "Offload result has no status."
        raise RuntimeError(msg)
    # Statistics are only meaningful (and only read) for a committed compaction.
    if status == "compacted":
        for field in _OFFLOAD_RESULT_INT_FIELDS:
            value = result.get(field)
            if not isinstance(value, int) or isinstance(value, bool):
                msg = (
                    f"Offload result field {field!r} must be an integer, got "
                    f"{type(value).__name__}."
                )
                raise RuntimeError(msg)  # noqa: TRY004  # protocol fault
    return cast("OffloadResult", result)


def _require_thread_id(config: Mapping[str, Any] | None) -> str:
    """Extract and validate that `thread_id` is present in config.

    Args:
        config: Config dict with `configurable.thread_id`.

    Returns:
        The thread ID string.

    Raises:
        ValueError: If `thread_id` is missing.
    """
    thread_id = (config or {}).get("configurable", {}).get("thread_id")
    if not thread_id:
        msg = "thread_id is required in config.configurable"

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Fix the server to emit statistics as JSON integers, or upgrade client/server to matching schema versions.
  2. Confirm the offending field name from the error message and inspect the server code computing it.
  3. If counts may legitimately be absent, decide whether to default them client-side (requires schema change) rather than sending null.
  4. Retry the compaction after the fix.

Example fix

// before: string counts
return {"status": "compacted", "total_tokens": "1234"}
// after: integer counts
return {"status": "compacted", "total_tokens": 1234}
Defensive patterns

Strategy: validation

Validate before calling

INT_FIELDS = ("total_tokens",)  # mirror _OFFLOAD_RESULT_INT_FIELDS
def stats_are_ints(result: dict) -> bool:
    return result.get("status") == "compacted" and all(
        isinstance(result.get(f), int) and not isinstance(result.get(f), bool)
        for f in INT_FIELDS
    )
if not stats_are_ints(raw): fix_server_serialization()

Type guard

def valid_stats(result: dict, fields: tuple[str, ...]) -> TypeGuard[dict]:
    return all(
        isinstance(result.get(f), int) and not isinstance(result.get(f), bool)
        for f in fields
    )

Try / catch

try:
    result = await aoffload(...)
except RuntimeError as exc:
    if "must be an integer" in str(exc):
        fix_field_type(exc)  # field name and actual type are in the message

Prevention

When it happens

Trigger: 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.

Common situations: JSON serialization emitting counts as strings; server-side rewrite of stats using floats; schema drift between client and server versions; `null` for unknown counts.

Related errors


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/0a76ea3f54ec324e. Report an issue: GitHub.