{"record":{"id":"9b43ecfe2ed12cd8","repo":"langchain-ai/deepagents","slug":"external-event-must-be-a-json-object","errorCode":null,"errorMessage":"External event must be a JSON object","messagePattern":"External event must be a JSON object","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/event_bus.py","lineNumber":381,"sourceCode":"        data: Raw JSON line.\n        source: Transport-specific source label attached to the event.\n\n    Returns:\n        Parsed external event.\n\n    Raises:\n        TypeError: If the envelope is not a JSON object.\n        ValueError: If any envelope field is missing, of the wrong type, or\n            otherwise invalid.\n    \"\"\"\n    try:\n        raw = json.loads(data)\n    except json.JSONDecodeError as exc:\n        msg = f\"External event must be valid JSON: {exc.msg}\"\n        raise ValueError(msg) from exc\n    if not isinstance(raw, dict):\n        msg = \"External event must be a JSON object\"\n        raise TypeError(msg)\n\n    kind = raw.get(\"kind\")\n    if kind not in _VALID_KINDS:\n        msg = f\"External event kind must be one of {sorted(_VALID_KINDS)}; got {kind!r}\"\n        raise ValueError(msg)\n\n    payload = raw.get(\"payload\")\n    if not isinstance(payload, str) or not payload.strip():\n        msg = \"External event payload must be a non-empty string\"\n        raise ValueError(msg)\n\n    bypass = raw.get(\"bypass\", BypassTier.QUEUED.value)\n    try:\n        bypass_tier = BypassTier(bypass)\n    except ValueError as exc:\n        msg = f\"External event bypass must be a valid bypass tier: {exc}\"\n        raise ValueError(msg) from exc\n","sourceCodeStart":363,"sourceCodeEnd":399,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/event_bus.py#L363-L399","documentation":"After JSON parsing succeeds, `decode_external_event` requires the decoded value to be a dict (JSON object) because the event envelope is accessed by field name. Any other JSON value — a string, number, array, boolean, or null — raises `TypeError`. This distinguishes shape errors (TypeError) from content errors (ValueError).","triggerScenarios":"Writing a bare JSON scalar or array to the external event socket, e.g. `\"hello\"`, `[1,2,3]`, `42`, or `null`, instead of an object like `{\"kind\":..., \"payload\":...}`.","commonSituations":"A producer sending a JSON array of events in one line instead of one object per line; sending just the payload string and forgetting the envelope; a misconfigured writer serializing a top-level list.","solutions":["Wrap the event in a JSON object envelope with `kind`, `payload`, and optional `bypass`/`correlation_id` fields.","On the producer, serialize a dict, not a list or scalar.","If emitting multiple events, write one JSON object per line (NDJSON), not an array.","Catch `TypeError` in the reader to report envelope-shape problems distinctly."],"exampleFix":"// before\necho '[{\"kind\":\"noop\",\"payload\":\"x\"}]' | socat - UNIX-CONNECT:$SOCK\n\n// after\necho '{\"kind\":\"noop\",\"payload\":\"x\"}' | socat - UNIX-CONNECT:$SOCK\n","handlingStrategy":"type-guard","validationCode":"import json\n\ndef assert_event_envelope(obj) -> None:\n    if not isinstance(obj, dict):\n        raise TypeError(f\"event must be a dict, got {type(obj).__name__}\")\n","typeGuard":"def is_event_envelope(value) -> bool:\n    return isinstance(value, dict) and \"kind\" in value and \"payload\" in value\n","tryCatchPattern":"try:\n    event = decode_external_event(data, source=source)\nexcept TypeError:\n    logger.warning(\"external event line is not a JSON object; envelope expected\")\n    return None\n","preventionTips":["Serialize a dict on the producer; never a bare list or scalar.","Emit one object per line, not an array of objects.","Keep a shared envelope-builder helper for all producers."],"tags":["json","ipc","event-bus","schema"],"backgroundTag":"invalid-json-payload","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}