{"record":{"id":"7af299dede5396e4","repo":"can1357/oh-my-pi","slug":"assistantmessageevent-contentindex-must-be-an-inte","errorCode":null,"errorMessage":"assistantMessageEvent.contentIndex must be an integer","messagePattern":"assistantMessageEvent\\.contentIndex must be an integer","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/omp-rpc/src/omp_rpc/protocol.py","lineNumber":353,"sourceCode":"        return AssistantMessageStartEvent(\n            type=\"start\",\n            partial=_parse_assistant_message(\n                _clone_json_object(\n                    payload.get(\"partial\"), field=\"assistantMessageEvent.partial\"\n                ),\n                field=\"assistantMessageEvent.partial\",\n            ),\n        )\n    if event_type in {\"text_start\", \"thinking_start\", \"toolcall_start\"}:\n        partial = _parse_assistant_message(\n            _clone_json_object(\n                payload.get(\"partial\"), field=\"assistantMessageEvent.partial\"\n            ),\n            field=\"assistantMessageEvent.partial\",\n        )\n        content_index = _optional_int(payload, \"contentIndex\")\n        if content_index is None:\n            raise ValueError(\"assistantMessageEvent.contentIndex must be an integer\")\n        if event_type == \"text_start\":\n            return AssistantTextStartEvent(\n                type=\"text_start\", contentIndex=content_index, partial=partial\n            )\n        if event_type == \"thinking_start\":\n            return AssistantThinkingStartEvent(\n                type=\"thinking_start\", contentIndex=content_index, partial=partial\n            )\n        return AssistantToolCallStartEvent(\n            type=\"toolcall_start\", contentIndex=content_index, partial=partial\n        )\n    if event_type in {\"text_delta\", \"thinking_delta\", \"toolcall_delta\"}:\n        partial = _parse_assistant_message(\n            _clone_json_object(\n                payload.get(\"partial\"), field=\"assistantMessageEvent.partial\"\n            ),\n            field=\"assistantMessageEvent.partial\",\n        )","sourceCodeStart":335,"sourceCodeEnd":371,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/python/omp-rpc/src/omp_rpc/protocol.py#L335-L371","documentation":"For 'text_start', 'thinking_start', and 'toolcall_start' assistant message events, contentIndex is required to locate the content block. The parser calls _optional_int, which returns None when the key is absent; the None result triggers this error. It is raised so the typed event always carries a valid integer index.","triggerScenarios":"Receiving an assistantMessageEvent of type text_start/thinking_start/toolcall_start whose payload omits contentIndex, or passes a non-int like \"0\", 1.5, true, or null; a buggy or outdated event emitter.","commonSituations":"Server emitting start events without the block index; JSON serialization turning ints into strings; protocol version drift between client and server.","solutions":["Ensure the event emitter includes contentIndex as a JSON integer on start events","Fix client/server version mismatch by upgrading omp-rpc on both sides","If consuming third-party events, sanitize the payload to add contentIndex before parsing","Reject or log the malformed notification upstream instead of parsing it"],"exampleFix":"// before\n{\"type\": \"text_start\", \"partial\": {...}}\n// after\n{\"type\": \"text_start\", \"contentIndex\": 0, \"partial\": {...}}","handlingStrategy":"validation","validationCode":"idx = event.get(\"contentIndex\")\nif event.get(\"type\") in {\"text_start\", \"thinking_start\", \"toolcall_start\"} and (\n    not isinstance(idx, int) or isinstance(idx, bool)\n):\n    raise ValueError(\"start event missing integer contentIndex\")","typeGuard":"def has_content_index(e: dict) -> bool:\n    v = e.get(\"contentIndex\")\n    return isinstance(v, int) and not isinstance(v, bool)","tryCatchPattern":"try:\n    event = parse_assistant_message_event(payload)\nexcept ValueError as e:\n    logger.warning(\"dropping malformed start event: %s\", e)\n    event = None","preventionTips":["Always emit contentIndex on start events","Never serialize ints as strings; booleans are rejected too","Test event emitters against the protocol parser"],"tags":["protocol","validation","streaming"],"backgroundTag":"missing-required-field","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}