{"record":{"id":"2e50d7561ead3ade","repo":"roboflow/supervision","slug":"createml-annotation-file-must-contain-a-json-list","errorCode":null,"errorMessage":"CreateML annotation file must contain a JSON list at the root, got {type(createml_data).__name__}.","messagePattern":"CreateML annotation file must contain a JSON list at the root, got (.+?)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/supervision/dataset/formats/createml.py","lineNumber":174,"sourceCode":"        - ``image_paths`` (``list[str]``): canonical resolved path for every\n          entry in the JSON, in file order.\n        - ``annotations`` (``dict[str, Detections]``): mapping from canonical\n          resolved image path to its ``Detections``.\n\n    Raises:\n        ValueError: If the JSON root is not a list.\n        ValueError: If an entry is missing the required ``\"image\"`` key.\n        ValueError: If an annotation is missing required coordinate or label keys.\n        ValueError: If two entries resolve to the same image path.\n        ValueError: If an annotation's ``image`` field resolves to the images\n            directory itself or to a path outside it (e.g. via ``..`` traversal\n            or an absolute path).\n    \"\"\"\n    createml_data = cast(\n        \"list[CreateMLDict]\", read_json_file(file_path=annotations_path)\n    )\n    if not isinstance(createml_data, list):\n        raise ValueError(\n            f\"CreateML annotation file must contain a JSON list at the root, \"\n            f\"got {type(createml_data).__name__}.\"\n        )\n\n    try:\n        classes = sorted(\n            {\n                annotation[\"label\"]\n                for entry in createml_data\n                for annotation in (entry.get(\"annotations\") or [])\n            }\n        )\n    except (KeyError, TypeError) as exc:\n        raise ValueError(\n            f\"Malformed CreateML annotation entry \"\n            f\"(missing or non-string 'label'): {exc}\"\n        ) from exc\n    class_to_index = {class_name: index for index, class_name in enumerate(classes)}","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/dataset/formats/createml.py#L156-L192","documentation":"Raised by load_createml_annotations when the parsed JSON root is not a list. The CreateML annotation format is a JSON array of {image, annotations} objects; read_json_file may return a dict (object root) or other types, and this check fails fast with the actual type name.","triggerScenarios":"Calling load_createml_annotations / DetectionDataset.from_createml with a file whose root is a JSON object (e.g. {\"images\": [...]}, a COCO-style file) or any non-array JSON.","commonSituations":"Passing a COCO annotations JSON to the CreateML loader by mistake; tool exporting CreateML data wrapped in an object with metadata; passing the wrong file path (e.g. a config JSON).","solutions":["Verify the file starts with '[' — CreateML format is a top-level array of entries.","If your data is COCO format, use load_coco_annotations instead.","If wrapped in an object, unwrap: data = json.load(f); entries = data['images'] and re-save as a list."],"exampleFix":"// before: file content\n{\"images\": [{\"image\": \"a.jpg\", \"annotations\": []}]}\n\n// after\n[{\"image\": \"a.jpg\", \"annotations\": []}]","handlingStrategy":"type-guard","validationCode":"import json\nfrom pathlib import Path\n\ndef load_createml_list(annotations_path: str) -> list:\n    \"\"\"Parse CreateML JSON and assert a list root before calling the loader.\"\"\"\n    data = json.loads(Path(annotations_path).read_text())\n    if not isinstance(data, list):\n        raise TypeError(f\"Expected JSON list root, got {type(data).__name__}\")\n    return data","typeGuard":"def is_createml_format(data: object) -> bool:\n    \"\"\"True when data is a list of dicts with an 'image' key.\"\"\"\n    return isinstance(data, list) and all(isinstance(e, dict) and \"image\" in e for e in data)","tryCatchPattern":"try:\n    sv.DetectionDataset.from_createml(images_directory_path=d, annotations_path=a)\nexcept ValueError as exc:\n    if \"JSON list at the root\" in str(exc):\n        raise TypeError(f\"{a} is not a CreateML file; check the format (COCO?)\") from exc\n    raise","preventionTips":["CreateML files are a top-level JSON array — verify the first non-whitespace byte is '['.","Keep format-specific loaders paired with the right file extension in your pipeline.","Write a tiny schema sniff test before bulk loading mixed datasets."],"tags":["createml","dataset-load","json","format-mismatch"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}