ruvnet/RuView · error · ManifestError

manifest must be an object with a 'markers' array

Error message

manifest must be an object with a 'markers' array

What it means

After parsing, load_manifest() requires the top level of scripts/fix-markers.json to be a JSON object containing a 'markers' key that is a list. It raises ManifestError('manifest must be an object with a \'markers\' array') when the parsed value is an array, a string, or an object whose 'markers' is missing or not a list. This is a shape check, not a syntax check — the JSON itself is valid.

Source

Thrown at scripts/check_fix_markers.py:75

OK_MARK = "PASS"
BAD_MARK = "FAIL"
ARROW = "->"


class ManifestError(Exception):
    pass


def load_manifest() -> dict:
    if not MANIFEST_PATH.exists():
        raise ManifestError(f"manifest not found: {MANIFEST_PATH}")
    try:
        data = json.loads(MANIFEST_PATH.read_text(encoding="utf-8"))
    except json.JSONDecodeError as e:
        raise ManifestError(f"manifest is not valid JSON: {e}") from e
    if not isinstance(data, dict) or not isinstance(data.get("markers"), list):
        raise ManifestError("manifest must be an object with a 'markers' array")
    ids = [m.get("id") for m in data["markers"]]
    dupes = {i for i in ids if ids.count(i) > 1}
    if dupes:
        raise ManifestError(f"duplicate marker ids: {sorted(dupes)}")
    return data


def _pattern_found(text: str, pattern: str) -> bool:
    if len(pattern) >= 2 and pattern.startswith("/") and pattern.endswith("/"):
        return re.search(pattern[1:-1], text, re.MULTILINE) is not None
    return pattern in text


def check_marker(marker: dict) -> tuple[bool, list[str]]:
    """Return (ok, problems) for a single marker."""
    problems: list[str] = []
    files = marker.get("files", [])
    require = marker.get("require", [])

View on GitHub (pinned to 4685618388)

Solutions

  1. Wrap the data as {"markers": [...]} with the list directly under the 'markers' key
  2. Ensure 'markers' is a JSON array of objects — not a dict keyed by marker id
  3. Check each element is an object with the expected 'id' field, since the duplicate check reads m.get('id')
  4. Re-run `python scripts/check_fix_markers.py --list` to confirm the manifest loads

Example fix

# before
[
  { "id": "RuView#396", "files": ["..."] }
]

# after
{
  "markers": [
    { "id": "RuView#396", "files": ["..."] }
  ]
}
Defensive patterns

Strategy: validation

Validate before calling

import json
from pathlib import Path

def manifest_shape_ok(path: str) -> bool:
    data = json.loads(Path(path).read_text(encoding="utf-8"))
    return isinstance(data, dict) and isinstance(data.get("markers"), list)

Type guard

def is_fix_marker_manifest(data: object) -> bool:
    return isinstance(data, dict) and isinstance(data.get("markers"), list)

Prevention

When it happens

Trigger: Writing the manifest as a bare top-level array of markers; nesting the markers list under a different key such as 'fixes' or 'entries'; having 'markers' hold an object (e.g. keyed by id) instead of a list.

Common situations: Contributors familiar with a different manifest format restructure the file; automated tools rewrite the JSON with a different top-level shape; copy-paste from another project's marker file.

Related errors


AI-assisted analysis of ruvnet/RuView@4685618388 (2026-08-16). Data as JSON: /api/errors/8ae5a7ce1ee1a887. Report an issue: GitHub.