warpdotdev/warp · error · MergeError

invalid_json

invalid_json

Error message

invalid_json

What it means

_decode_document() parses the bytes read from the config as UTF-8 JSON; UnicodeError (non-UTF-8 bytes, e.g. UTF-16 or a BOM) or json.JSONDecodeError (malformed JSON — comments, trailing commas, truncation, bad quotes) raises invalid_json. The tool requires strict JSON: JSONC with // comments fails exactly here.

Source

Thrown at resources/bundled/skills/tui-migrate-setup/scripts/merge_mcp_config.py:138

    flags = os.O_RDONLY
    if hasattr(os, "O_NOFOLLOW"):
        flags |= os.O_NOFOLLOW
    try:
        descriptor = os.open(path, flags)
        with os.fdopen(descriptor, "rb") as file:
            raw = file.read(MAX_CONFIG_BYTES + 1)
    except OSError as error:
        raise MergeError("config_unavailable") from error
    if len(raw) > MAX_CONFIG_BYTES:
        raise MergeError("config_too_large")
    return raw, stat.S_IMODE(metadata.st_mode)


def _decode_document(raw: bytes) -> dict[str, Any]:
    try:
        document = json.loads(raw.decode("utf-8"))
    except (UnicodeError, json.JSONDecodeError) as error:
        raise MergeError("invalid_json") from error
    if not isinstance(document, dict):
        raise MergeError("invalid_config_shape")
    return document


def _detect_wrapper(document: dict[str, Any]) -> tuple[tuple[str, ...], dict[str, Any]]:
    matches: list[tuple[tuple[str, ...], dict[str, Any]]] = []
    for wrapper_path in WRAPPER_PATHS:
        value = _path_value(document, wrapper_path)
        if value is not None:
            if not isinstance(value, dict):
                raise MergeError("invalid_wrapper_shape")
            matches.append((wrapper_path, value))

    if len(matches) > 1:
        raise MergeError("ambiguous_wrapper")
    if matches:
        return matches[0]

View on GitHub (pinned to e72fd7aacb)

Solutions

  1. Validate: python -m json.tool FILE — fix the exact line it reports
  2. Remove comments and trailing commas; the config must be strict JSON
  3. Re-save as UTF-8 without BOM if the failure came from decoding rather than syntax

Example fix

// before
{
  "mcpServers": {
    // my favorite server
    "fetch": { "command": "uvx", "args": ["mcp-server-fetch",] }
  }
}

// after
{
  "mcpServers": {
    "fetch": { "command": "uvx", "args": ["mcp-server-fetch"] }
  }
}
Defensive patterns

Strategy: validation

Validate before calling

import json
from pathlib import Path

json.loads(Path(p).read_bytes().decode('utf-8'))  # strict JSON, no BOM, no comments

Type guard

def is_strict_json_object(raw: bytes) -> bool:
    try:
        return isinstance(json.loads(raw.decode('utf-8')), dict)
    except (UnicodeError, json.JSONDecodeError):
        return False

Try / catch

if result.returncode != 0 and 'invalid_json' in result.stderr:
    # python -m json.tool <path> reports the exact line; fix, then re-run the merge
    ...

Prevention

When it happens

Trigger: Config edited by hand with // comments or a trailing comma; file saved as UTF-16 or UTF-8-with-BOM; truncated write after a crash; a TOML/YAML file passed where JSON is expected.

Common situations: Users adding comments because their editor permits JSONC; crash-truncated configs; tools that emit JSONC by default; wrong-file mixups in dotfiles.

Related errors


AI-assisted analysis of warpdotdev/warp@e72fd7aacb (2026-08-16). Data as JSON: /api/errors/b1767d65a5697d24. Report an issue: GitHub.