tirth8205/code-review-graph · error · ValueError

expected JSON array

Error message

expected JSON array

What it means

Raised by _array_elements when the token at the given index is not the '[' that opens a JSON array (or the index is past the token stream end). The path being edited assumed an array at that position, but the document has a different token there. Companion to 'expected JSON object' for the array case.

Source

Thrown at code_review_graph/uninstall.py:297

        if key_token.kind != "string" or not isinstance(key_token.value, str):
            raise ValueError("expected JSON object key")
        if cursor + 1 >= len(tokens) or tokens[cursor + 1].kind != ":":
            raise ValueError("expected colon after JSON object key")
        value_index = cursor + 2
        value_end = _skip_value(tokens, value_index)
        comma_index = value_end if (
            value_end < len(tokens) and tokens[value_end].kind == ","
        ) else None
        members.append(
            _Member(key_token.value, cursor, value_index, value_end, comma_index)
        )
        cursor = value_end + 1 if comma_index is not None else value_end
    return members


def _array_elements(tokens: Sequence[_Token], index: int) -> list[_Element]:
    if index >= len(tokens) or tokens[index].kind != "[":
        raise ValueError("expected JSON array")
    elements: list[_Element] = []
    cursor = index + 1
    while cursor < len(tokens) and tokens[cursor].kind != "]":
        if tokens[cursor].kind == ",":  # trailing comma
            cursor += 1
            continue
        value_end = _skip_value(tokens, cursor)
        comma_index = value_end if (
            value_end < len(tokens) and tokens[value_end].kind == ","
        ) else None
        elements.append(_Element(cursor, value_end, comma_index))
        cursor = value_end + 1 if comma_index is not None else value_end
    return elements


def _find_value(tokens: Sequence[_Token], path: Sequence[str | int]) -> int:
    if not tokens:
        raise ValueError("empty JSON document")

View on GitHub (pinned to b58668751a)

Solutions

  1. Confirm the parent value at that path step is actually an array; if it's an object, use the string key instead of an index
  2. Validate the document structure (json.loads on comment-stripped text, check isinstance(list)) before removal
  3. Repair unbalanced brackets if the file was hand-edited
  4. Catch ValueError and skip the edit, logging the file for manual follow-up

Example fix

# before
# config: {"servers": {"graph": {}}}
remove_jsonc_paths(text, ["servers", 0])  # -> expected JSON array

# after
remove_jsonc_paths(text, ["servers", "graph"])
Defensive patterns

Strategy: validation

Validate before calling

import json, re
def resolves_to_array(text: str, path: list) -> bool:
    try:
        cur = json.loads(re.sub(r"//[^\n]*|/\*.*?\*/", "", text, flags=re.S))
        for c in path:
            cur = cur[c]
        return isinstance(cur, list)
    except (ValueError, KeyError, IndexError, TypeError):
        return False

Type guard

def is_int_path_component(c) -> bool:
    return isinstance(c, int) and not isinstance(c, bool)

Try / catch

try:
    _remove_jsonc_paths(text, paths)
except ValueError as e:
    log.warning("path shape mismatch: %s", e)

Prevention

When it happens

Trigger: Removing an indexed path element (e.g. path [..., 0]) whose parent resolves to an object, string, or number instead of an array; malformed/truncated JSONC where the '[' is missing; using an int component against a key-value container.

Common situations: Path built with numeric indices for what is actually an object of named keys (e.g. tools stored as {"name": {...}} not [...]); config format changed between versions from array to object; hand-edit broke the array brackets.

Related errors


AI-assisted analysis of tirth8205/code-review-graph@b58668751a (2026-08-28). Data as JSON: /api/errors/d554837600198820. Report an issue: GitHub.