roboflow/supervision · error · ValueError
Malformed CreateML annotation entry (missing or non-string '
Error message
Malformed CreateML annotation entry (missing or non-string 'label'): {exc} What it means
Raised by load_createml_annotations when collecting the class set across all entries fails with KeyError/TypeError — i.e. some annotation lacks a 'label' key or has a non-subscriptable shape. The loader derives the sorted class list from every annotation's label before building class_to_index, so one malformed annotation aborts the load.
Source
Thrown at src/supervision/dataset/formats/createml.py:188
createml_data = cast(
"list[CreateMLDict]", read_json_file(file_path=annotations_path)
)
if not isinstance(createml_data, list):
raise ValueError(
f"CreateML annotation file must contain a JSON list at the root, "
f"got {type(createml_data).__name__}."
)
try:
classes = sorted(
{
annotation["label"]
for entry in createml_data
for annotation in (entry.get("annotations") or [])
}
)
except (KeyError, TypeError) as exc:
raise ValueError(
f"Malformed CreateML annotation entry "
f"(missing or non-string 'label'): {exc}"
) from exc
class_to_index = {class_name: index for index, class_name in enumerate(classes)}
image_paths: list[str] = []
annotations: dict[str, Detections] = {}
for entry in tqdm(
createml_data,
desc="Loading CreateML annotations",
disable=not show_progress,
):
image_name = entry.get("image")
if image_name is None:
raise ValueError(
f"CreateML annotation entry is missing the required 'image' key: "
f"{entry!r}"
)View on GitHub (pinned to 7f254d9784)
Solutions
- Scan the JSON for annotations without a string 'label' field and add or rename it.
- If your source uses a different key, transform it: ann['label'] = ann.pop('category').
- Drop null/non-dict items from annotations arrays before loading.
Example fix
// before
{"image": "a.jpg", "annotations": [{"coordinates": {...}}]}
// after
{"image": "a.jpg", "annotations": [{"label": "dog", "coordinates": {...}}]} Defensive patterns
Strategy: validation
Validate before calling
import json
from pathlib import Path
def validate_createml_labels(annotations_path: str) -> None:
"""Fail fast if any annotation lacks a string 'label'."""
entries = json.loads(Path(annotations_path).read_text())
for e in entries:
for ann in e.get("annotations") or []:
if not isinstance(ann, dict) or not isinstance(ann.get("label"), str):
raise ValueError(f"Malformed annotation in entry {e.get('image')!r}: {ann!r}") Type guard
def has_valid_labels(entry: dict) -> bool:
"""True when every annotation in the entry carries a string label."""
anns = entry.get("annotations") or []
return all(isinstance(a, dict) and isinstance(a.get("label"), str) for a in anns) Try / catch
try:
sv.DetectionDataset.from_createml(images_directory_path=d, annotations_path=a)
except ValueError as exc:
if "missing or non-string 'label'" in str(exc):
validate_createml_labels(a) # raises with the precise offending entry
raise Prevention
- Schema-check third-party CreateML files before bulk loading.
- Standardize on the 'label' key in any converter you write.
- Filter null/non-dict items out of annotations arrays at ingest time.
When it happens
Trigger: Any entry in the annotations array of the CreateML JSON missing "label", or an annotations list containing non-dict items (TypeError on annotation["label"]).
Common situations: Partially exported or hand-edited files; annotations written by a tool that names the field differently (e.g. 'class' or 'category'); null entries inside annotations arrays.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- CreateML annotation refers to image {image_name}, which reso
- CreateML annotation refers to image {image_name}, which reso
- CreateML annotation entry is missing the required 'image' ke
- CreateML annotation file contains duplicate entries for imag
- Malformed CreateML annotation entry {annotation}: {exc}
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/d3e714bcca52416c.
Report an issue: GitHub.