{
  "id": "llm/function-call-arguments-truncated-in-streaming",
  "signature": "json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 1024 (char 1023) when parsing streaming function call arguments",
  "signature_zh": "json.decoder.JSONDecodeError: 期望属性名称用双引号括起来：在解析流式函数调用参数时，第 1 行第 1024 列（字符 1023）",
  "regex": "json\\.decoder\\.JSONDecodeError: Expecting property name enclosed in double quotes.*streaming function call arguments",
  "domain": "llm",
  "category": "protocol_error",
  "subcategory": null,
  "root_cause": "When streaming function calls, the API sends the arguments in chunks. If the argument string is long, a chunk boundary can split a JSON token (e.g., a string value or key), causing the accumulated arguments to be invalid JSON when parsed incrementally.",
  "root_cause_type": "generic",
  "root_cause_zh": "当流式传输函数调用时，API 会分块发送参数。如果参数字符串很长，块边界可能会分割 JSON 令牌（例如，字符串值或键），导致在增量解析时累积的参数成为无效 JSON。",
  "versions": [
    {
      "version": "openai==1.30.0",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "anthropic==0.25.0",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    },
    {
      "version": "mistralai==0.1.0",
      "introduced": null,
      "deprecated": null,
      "removed": null,
      "behavior_change": null,
      "status": "active"
    }
  ],
  "os_specific": {},
  "dead_ends": [
    {
      "action": "Using json.loads() on each individual chunk instead of accumulating",
      "why_fails": "Individual chunks are not valid JSON; they are partial fragments. json.loads() will always fail on incomplete chunks.",
      "fail_rate": 0.95,
      "condition": "",
      "sources": []
    },
    {
      "action": "Increasing max_tokens to reduce chunking",
      "why_fails": "max_tokens controls the output length, not the chunk size. The API still sends chunks of arbitrary size regardless of max_tokens.",
      "fail_rate": 0.8,
      "condition": "",
      "sources": []
    },
    {
      "action": "Setting stream_options={'include_usage': True}",
      "why_fails": "This option controls whether usage information is included in the stream, it has no effect on how function call arguments are chunked or parsed.",
      "fail_rate": 0.9,
      "condition": "",
      "sources": []
    }
  ],
  "workarounds": [
    {
      "action": "Accumulate all chunks for a function call before attempting to parse. Wait for the 'finish_reason' to be 'stop' or 'function_call' before parsing the complete arguments string. Example:\n\nfull_args = \"\"\nfor chunk in stream:\n    delta = chunk.choices[0].delta\n    if delta.function_call and delta.function_call.arguments:\n        full_args += delta.function_call.arguments\n    if chunk.choices[0].finish_reason:\n        break\nimport json\nparsed_args = json.loads(full_args)",
      "success_rate": 0.95,
      "how": "Accumulate all chunks for a function call before attempting to parse. Wait for the 'finish_reason' to be 'stop' or 'function_call' before parsing the complete arguments string. Example:\n\nfull_args = \"\"\nfor chunk in stream:\n    delta = chunk.choices[0].delta\n    if delta.function_call and delta.function_call.arguments:\n        full_args += delta.function_call.arguments\n    if chunk.choices[0].finish_reason:\n        break\nimport json\nparsed_args = json.loads(full_args)",
      "condition": "",
      "sources": []
    },
    {
      "action": "Use the 'incremental parsing' approach with a JSON repair library like 'json-repair' or 'json5' that can handle partial JSON. Example:\n\nimport json5\npartial_args = \"\"\nfor chunk in stream:\n    delta = chunk.choices[0].delta\n    if delta.function_call and delta.function_call.arguments:\n        partial_args += delta.function_call.arguments\n        try:\n            parsed = json5.loads(partial_args)\n            # use parsed incrementally\n        except Exception:\n            pass",
      "success_rate": 0.82,
      "how": "Use the 'incremental parsing' approach with a JSON repair library like 'json-repair' or 'json5' that can handle partial JSON. Example:\n\nimport json5\npartial_args = \"\"\nfor chunk in stream:\n    delta = chunk.choices[0].delta\n    if delta.function_call and delta.function_call.arguments:\n        partial_args += delta.function_call.arguments\n        try:\n            parsed = json5.loads(partial_args)\n            # use parsed incrementally\n        except Exception:\n            pass",
      "condition": "",
      "sources": []
    },
    {
      "action": "Set the API parameter 'stream_options' to {'include_usage': True} and use the 'usage' field to detect the end of function call arguments, then parse the complete string.",
      "success_rate": 0.75,
      "how": "Set the API parameter 'stream_options' to {'include_usage': True} and use the 'usage' field to detect the end of function call arguments, then parse the complete string.",
      "condition": "",
      "sources": []
    }
  ],
  "workarounds_zh": [
    "在尝试解析之前，累积函数调用的所有块。等待 'finish_reason' 为 'stop' 或 'function_call' 后再解析完整的参数字符串。示例：\n\nfull_args = \"\"\nfor chunk in stream:\n    delta = chunk.choices[0].delta\n    if delta.function_call and delta.function_call.arguments:\n        full_args += delta.function_call.arguments\n    if chunk.choices[0].finish_reason:\n        break\nimport json\nparsed_args = json.loads(full_args)",
    "使用 '增量解析' 方法，配合 JSON 修复库（如 'json-repair' 或 'json5'）处理部分 JSON。示例：\n\nimport json5\npartial_args = \"\"\nfor chunk in stream:\n    delta = chunk.choices[0].delta\n    if delta.function_call and delta.function_call.arguments:\n        partial_args += delta.function_call.arguments\n        try:\n            parsed = json5.loads(partial_args)\n            # 增量使用解析结果\n        except Exception:\n            pass",
    "设置 API 参数 'stream_options' 为 {'include_usage': True}，并使用 'usage' 字段检测函数调用参数的结束，然后解析完整字符串。"
  ],
  "transition_graph": {
    "leads_to": [],
    "preceded_by": [],
    "frequently_confused_with": []
  },
  "official_doc_url": "https://platform.openai.com/docs/guides/function-calling#streaming-function-calls",
  "official_doc_section": null,
  "error_code": null,
  "verification_tier": "ai_generated",
  "confidence": 0.89,
  "fix_success_rate": 0.85,
  "resolvable": "true",
  "first_seen": "2024-04-01",
  "last_confirmed": "2024-06-01",
  "last_updated": "2024-06-01",
  "evidence_count": 1,
  "tags": [],
  "locale": "en",
  "aliases": []
}