sgl-project/sglang · error · ValueError

Invalid format: keys must be integers (or string representat

Error message

Invalid format: keys must be integers (or string representations of integers) and values must be strings

What it means

The mapping parsed into a dict, but at least one entry violates the schema: keys must be integers or digit-strings convertible to int (checked via str(gpu_key).isdigit()), and each value must be a string. parse_ib_device_config raises ValueError while normalizing entries into Dict[int, str].

Source

Thrown at python/sglang/srt/distributed/device_communicators/mooncake_transfer_engine.py:65

            raise RuntimeError(
                f"Failed to read JSON file {normalized_input}: {exc}"
            ) from exc
    else:
        try:
            mapping = json.loads(normalized_input)
        except json.JSONDecodeError as exc:
            raise ValueError(f"Invalid JSON mapping: {normalized_input}") from exc

    if not isinstance(mapping, dict):
        raise ValueError(
            "Invalid format: expected a mapping from GPU id to IB device string"
        )

    normalized_mapping: Dict[int, str] = {}
    for gpu_key, ib_devices in mapping.items():
        normalized_key = int(gpu_key) if str(gpu_key).isdigit() else None
        if normalized_key is None or not isinstance(ib_devices, str):
            raise ValueError(
                "Invalid format: keys must be integers (or string "
                "representations of integers) and values must be strings"
            )
        normalized_mapping[normalized_key] = ib_devices.strip()

    if not normalized_mapping:
        raise ValueError("No valid GPU mappings found in JSON")

    return normalized_mapping


def get_ib_devices_for_gpu(ib_device_str: Optional[str], gpu_id: int) -> Optional[str]:
    """
    Parse IB device string and get IB devices for a specific GPU ID.

    Supports all the following formats:
    1. Old format: "ib0, ib1, ib2"
    2. New format: {0: "ib0, ib1", 1: "ib2, ib3", 2: "ib4"}

View on GitHub (pinned to 0132848349)

Solutions

  1. Make every key a plain non-negative integer or its string form and every value a comma-separated string: {"0": "mlx5_0,mlx5_1"}
  2. Lint the mapping before launch: all(str(k).isdigit() and isinstance(v, str) for k, v in json.load(open(path)).items())

Example fix

# before
{"0": ["mlx5_0", "mlx5_1"]}

# after
{"0": "mlx5_0,mlx5_1"}
Defensive patterns

Strategy: validation

Validate before calling

import json

def lint_ib_mapping(path: str) -> None:
    m = json.load(open(path))
    for k, v in m.items():
        assert str(k).isdigit(), f"key {k!r} must be an integer"
        assert isinstance(v, str) and v.strip(), f"value for {k!r} must be a non-empty string"

Type guard

def valid_entries(m: dict) -> bool:
    return all(str(k).isdigit() and isinstance(v, str) for k, v in m.items())

Try / catch

parsed = json.loads(cfg) if cfg.strip().startswith("{") else cfg
if isinstance(parsed, dict) and not valid_entries(parsed):
    raise ConfigError("IB mapping values must be strings; use 'dev0,dev1' not lists")
parse_ib_device_config(cfg)

Prevention

When it happens

Trigger: Keys like "gpu0", 0.5, or null, or values that are numbers/arrays (e.g. {"0": ["mlx5_0"]} or {0: 5}). str.isdigit() also rejects negative keys and non-ASCII digits.

Common situations: Modeling the value as a list of devices per GPU, using float GPU ids, or a mapping template with wrong value types.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/4c2140c7a50d0821. Report an issue: GitHub.