can1357/oh-my-pi · error · ValueError

assistantMessageEvent.contentIndex must be an integer

Error message

assistantMessageEvent.contentIndex must be an integer

What it means

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.

Source

Thrown at python/omp-rpc/src/omp_rpc/protocol.py:353

        return AssistantMessageStartEvent(
            type="start",
            partial=_parse_assistant_message(
                _clone_json_object(
                    payload.get("partial"), field="assistantMessageEvent.partial"
                ),
                field="assistantMessageEvent.partial",
            ),
        )
    if event_type in {"text_start", "thinking_start", "toolcall_start"}:
        partial = _parse_assistant_message(
            _clone_json_object(
                payload.get("partial"), field="assistantMessageEvent.partial"
            ),
            field="assistantMessageEvent.partial",
        )
        content_index = _optional_int(payload, "contentIndex")
        if content_index is None:
            raise ValueError("assistantMessageEvent.contentIndex must be an integer")
        if event_type == "text_start":
            return AssistantTextStartEvent(
                type="text_start", contentIndex=content_index, partial=partial
            )
        if event_type == "thinking_start":
            return AssistantThinkingStartEvent(
                type="thinking_start", contentIndex=content_index, partial=partial
            )
        return AssistantToolCallStartEvent(
            type="toolcall_start", contentIndex=content_index, partial=partial
        )
    if event_type in {"text_delta", "thinking_delta", "toolcall_delta"}:
        partial = _parse_assistant_message(
            _clone_json_object(
                payload.get("partial"), field="assistantMessageEvent.partial"
            ),
            field="assistantMessageEvent.partial",
        )

View on GitHub (pinned to 9690622007)

Solutions

  1. Ensure the event emitter includes contentIndex as a JSON integer on start events
  2. Fix client/server version mismatch by upgrading omp-rpc on both sides
  3. If consuming third-party events, sanitize the payload to add contentIndex before parsing
  4. Reject or log the malformed notification upstream instead of parsing it

Example fix

// before
{"type": "text_start", "partial": {...}}
// after
{"type": "text_start", "contentIndex": 0, "partial": {...}}
Defensive patterns

Strategy: validation

Validate before calling

idx = event.get("contentIndex")
if event.get("type") in {"text_start", "thinking_start", "toolcall_start"} and (
    not isinstance(idx, int) or isinstance(idx, bool)
):
    raise ValueError("start event missing integer contentIndex")

Type guard

def has_content_index(e: dict) -> bool:
    v = e.get("contentIndex")
    return isinstance(v, int) and not isinstance(v, bool)

Try / catch

try:
    event = parse_assistant_message_event(payload)
except ValueError as e:
    logger.warning("dropping malformed start event: %s", e)
    event = None

Prevention

When it happens

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

Common situations: Server emitting start events without the block index; JSON serialization turning ints into strings; protocol version drift between client and server.

Understand the failure class

Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/7af299dede5396e4. Report an issue: GitHub.