{"record":{"id":"c1016894763d0398","repo":"PaddlePaddle/PaddleOCR","slug":"cannot-found-key-cls-in-ann-keys-please-check","errorCode":null,"errorMessage":"Cannot found 'key_cls' in ann.keys(), please check your training annotation.","messagePattern":"Cannot found 'key_cls' in ann\\.keys\\(\\), please check your training annotation\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"ppocr/data/imaug/label_ops.py","lineNumber":435,"sourceCode":"            box = ann[\"points\"]\n            x_list = [box[i][0] for i in range(4)]\n            y_list = [box[i][1] for i in range(4)]\n            sorted_x_list, sorted_y_list = self.sort_vertex(x_list, y_list)\n            sorted_box = []\n            for x, y in zip(sorted_x_list, sorted_y_list):\n                sorted_box.append(x)\n                sorted_box.append(y)\n            boxes.append(sorted_box)\n            text = ann[\"transcription\"]\n            texts.append(ann[\"transcription\"])\n            text_ind = [self.dict[c] for c in text if c in self.dict]\n            text_inds.append(text_ind)\n            if \"label\" in ann.keys():\n                labels.append(self.label2classid_map[ann[\"label\"]])\n            elif \"key_cls\" in ann.keys():\n                labels.append(ann[\"key_cls\"])\n            else:\n                raise ValueError(\n                    \"Cannot found 'key_cls' in ann.keys(), please check your training annotation.\"\n                )\n            edges.append(ann.get(\"edge\", 0))\n        ann_infos = dict(\n            image=data[\"image\"],\n            points=boxes,\n            texts=texts,\n            text_inds=text_inds,\n            edges=edges,\n            labels=labels,\n        )\n\n        return self.list_to_numpy(ann_infos)\n\n\nclass AttnLabelEncode(BaseRecLabelEncode):\n    \"\"\"Convert between text-label and text-index\"\"\"\n","sourceCodeStart":417,"sourceCodeEnd":453,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/ppocr/data/imaug/label_ops.py#L417-L453","documentation":"During KIE (key information extraction) training, the label converter builds per-box class labels. For each annotation dict it first looks for a 'label' key (mapped through label2classid_map from the class_list file), then a 'key_cls' key used directly. If neither exists it raises ValueError telling you the training annotation is missing the class field.","triggerScenarios":"Training a KIE model (e.g. SDMGR, configs/kie/) where the label file lines contain JSON annotations that have 'transcription' and 'points' but neither 'label' nor 'key_cls'.","commonSituations":"Using a plain OCR-format detection label file for KIE training; converting labels with a script that drops the key_cls field; wild-receipt dataset with custom preprocessing that renamed key_cls to something else.","solutions":["Regenerate the label file so each annotation includes \"key_cls\": <class_id> (integer), e.g. {\"transcription\": \"TOTAL\", \"points\": [...], \"key_cls\": 5}","Or add a \"label\" field with the class name and provide the matching class_list_file (e.g. train_data/class_list.txt) so label2classid_map can resolve it","Sanity-check a few lines: python -c 'import json; [print(json.loads(l)[0].keys()) for l in open(\"train_label.txt\")][:3]'","Compare your label format against the wildreceipt annotation format shipped with the KIE docs"],"exampleFix":"// before (label line)\n[{\"transcription\": \"TOTAL\", \"points\": [[1,2],[3,4]]}]\n// after\n[{\"transcription\": \"TOTAL\", \"points\": [[1,2],[3,4]], \"key_cls\": 1}]","handlingStrategy":"validation","validationCode":"import json\nfor path in label_file_list:\n    for line in open(path, encoding='utf-8'):\n        anns = json.loads(line.strip())\n        for ann in anns:\n            if 'label' not in ann and 'key_cls' not in ann:\n                raise SystemExit(f'{path}: annotation missing key_cls/label: {ann}')","typeGuard":"def is_valid_kie_annotation(ann: dict) -> bool:\n    return ('transcription' in ann and 'points' in ann\n            and ('label' in ann or 'key_cls' in ann))","tryCatchPattern":"try:\n    batch = converter(annotations)\nexcept ValueError as e:\n    if 'key_cls' in str(e):\n        raise ValueError(f'KIE label file lacks key_cls/label fields: {e}') from e\n    raise","preventionTips":["Run a label-file lint step (check keys of every JSON annotation) before training","Keep the class_list_file next to the labels and version them together","Automate KIE label conversion from raw annotations instead of hand-editing"],"tags":["annotation","kie","data-format","training"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}