{"record":{"id":"21da433614299c6a","repo":"HumanSignal/label-studio","slug":"prediction-validation-failed-len-validation-erro","errorCode":null,"errorMessage":"Prediction validation failed ({len(validation_errors)} errors):\\n- {error}\\n","messagePattern":"Prediction validation failed \\((.+?) errors\\):\\\\n- (.+?)\\\\n","errorType":"validation","errorClass":"ValidationError","httpStatus":400,"severity":"error","filePath":"label_studio/data_import/api.py","lineNumber":317,"sourceCode":"            for i, task in enumerate(parsed_data):\n                if 'predictions' in task:\n                    for j, prediction in enumerate(task['predictions']):\n                        try:\n                            validation_errors_list = li.validate_prediction(prediction, return_errors=True)\n                            if validation_errors_list:\n                                for error in validation_errors_list:\n                                    validation_errors.append(f'Task {i}, prediction {j}: {error}')\n                        except Exception as e:\n                            error_msg = f'Task {i}, prediction {j}: Error validating prediction - {extract_message(e)}'\n                            validation_errors.append(error_msg)\n\n            if validation_errors:\n                error_message = f'Prediction validation failed ({len(validation_errors)} errors):\\n'\n                for error in validation_errors:\n                    error_message += f'- {error}\\n'\n\n                if flag_set('fflag_feat_utc_210_prediction_validation_15082025', user='auto'):\n                    raise ValidationError({'predictions': [error_message]})\n                else:\n                    logger.error(\n                        f'Prediction validation failed, not raising error - ({len(validation_errors)} errors):\\n{error_message}'\n                    )\n\n        if commit_to_project:\n            # Immediately create project tasks and update project states and counters\n            tasks, serializer = self._save(parsed_data)\n            task_count = len(tasks)\n            annotation_count = len(serializer.db_annotations)\n            prediction_count = len(serializer.db_predictions)\n\n            recalculate_stats_counts = {\n                'task_count': task_count,\n                'annotation_count': annotation_count,\n                'prediction_count': prediction_count,\n            }\n","sourceCodeStart":299,"sourceCodeEnd":335,"githubUrl":"https://github.com/HumanSignal/label-studio/blob/0b49e9b53917880baf1dd85d574fe5541a9aafb2/label_studio/data_import/api.py#L299-L335","documentation":"Label Studio's sync_import (POST /api/projects/{id}/import) validates prediction payloads against the project's label config when predictions are included with imported tasks. When any prediction fails validation and the feature flag 'fflag_feat_utc_210_prediction_validation_15082025' is enabled, it aggregates all validation errors into a single DRF ValidationError listing each problem on its own line. Without the flag the errors are only logged and the import proceeds.","triggerScenarios":"POSTing tasks with a 'predictions' array to the import endpoint where a prediction references a result whose from_name/to_name/labels do not match the project labeling config, or has a malformed result structure. Only raised when commit_to_project is true and the prediction-validation feature flag is on.","commonSituations":"Re-importing annotations exported from a project whose label config was changed since export; programmatic pre-annotation generation with wrong label names; migrating projects between instances with different label configs; an org recently enabling the prediction-validation flag so imports that previously 'worked' (silently skipping bad predictions) start failing.","solutions":["Read the per-line error messages in the response; each '- {error}' names the offending prediction field","Compare the prediction result keys (from_name, to_name, labels) against the project's labeling config via GET /api/projects/{id}/","Fix or remove the invalid predictions from the import payload and retry","If legacy behavior is needed, ask an admin to disable fflag_feat_utc_210_prediction_validation_15082025 (not recommended)","Use POST /api/projects/{id}/validate or the label-config validation endpoint to pre-check payload compatibility"],"exampleFix":"// before: prediction labels don't match config\n{\"data\": {\"text\": \"hi\"}, \"predictions\": [{\"result\": [{\"from_name\": \"sentiment\", \"to_name\": \"text\", \"type\": \"choices\", \"value\": {\"choices\": [\"happy\"]}}]}]}\n// after: labels match <Choices name=\"sentiment\"> <Choice value=\"positive\"/> ...\n{\"data\": {\"text\": \"hi\"}, \"predictions\": [{\"result\": [{\"from_name\": \"sentiment\", \"to_name\": \"text\", \"type\": \"choices\", \"value\": {\"choices\": [\"positive\"]}}]}]}","handlingStrategy":"try-catch","validationCode":"import re, requests\ncfg = requests.get(f'{LS}/api/projects/{pid}/', headers=H).json()['label_config']\nlabels = set(re.findall(r'<Choice\\s+value=\"([^\"]+)\"', cfg))\nfor t in tasks:\n    for p in t.get('predictions', []):\n        for r in p.get('result', []):\n            for ch in r.get('value', {}).get('choices', []):\n                assert ch in labels, f'label {ch!r} not in config'","typeGuard":null,"tryCatchPattern":"try:\n    requests.post(f'{LS}/api/projects/{pid}/import', headers=H, json=tasks).raise_for_status()\nexcept requests.HTTPError as e:\n    detail = e.response.json()\n    msg = detail.get('predictions', detail.get('detail', ''))\n    lines = [l[2:] for l in str(msg).splitlines() if l.startswith('- ')]\n    log.error('Prediction validation failed: %s', lines)","preventionTips":["Keep label configs in version control and regenerate predictions whenever the config changes","Pre-validate result labels against GET /api/projects/{id}/ before every bulk import","Know whether the prediction-validation feature flag is enabled in your deployment"],"tags":["django","rest-framework","import","predictions","validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"0b49e9b53917880baf1dd85d574fe5541a9aafb2","analyzedAt":"2026-08-29T00:39:52.578Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}