{"record":{"id":"209bf4f0ff2022e3","repo":"HumanSignal/label-studio","slug":"unsupported-or-invalid-json-structure","errorCode":null,"errorMessage":"Unsupported or invalid JSON structure","messagePattern":"Unsupported or invalid JSON structure","errorType":"validation","errorClass":"ValidationError","httpStatus":400,"severity":"error","filePath":"label_studio/data_import/models.py","lineNumber":211,"sourceCode":"                        formatted_task = self._format_task_for_json_streaming(task)\n                        batch.append(formatted_task)\n                        if len(batch) >= batch_size:\n                            yield batch\n                            batch = []\n\n                elif first_byte == ord('{'):\n                    # Single JSON object: parse once and yield a single-item batch\n                    raw_data = file_handle.read()\n                    try:\n                        task_data = json.loads(raw_data)\n                    except TypeError:\n                        task_data = json.loads(raw_data.decode('utf8'))\n                    formatted_task = self._format_task_for_json_streaming(task_data)\n                    batch.append(formatted_task)\n\n                else:\n                    # Unknown/invalid JSON structure\n                    raise ValidationError('Unsupported or invalid JSON structure')\n\n                # Yield remaining tasks if any\n                if batch:\n                    yield batch\n\n        except Exception as exc:\n            raise ValidationError(f'Failed to parse JSON file {self.file_name}: {extract_message(exc)}')\n\n    def _format_task_for_json_streaming(self, task):\n        \"\"\"Format task data for JSON streaming consistency with read_tasks_list_from_json\"\"\"\n        # Handle different task types as in the original read_tasks_list_from_json method\n        if isinstance(task, dict):\n            if not task.get('data'):\n                task = {'data': task}\n        else:\n            # If task is not a dict (e.g., list), wrap it in {'data': task}\n            task = {'data': task}\n","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/HumanSignal/label-studio/blob/0b49e9b53917880baf1dd85d574fe5541a9aafb2/label_studio/data_import/models.py#L193-L229","documentation":"The streaming JSON reader accepts only a top-level JSON array, a single object, or line-delimited objects; anything else (scalar, bare string array handled elsewhere, malformed nesting) hits the fall-through branch and raises this ValidationError.","triggerScenarios":"read_tasks_streaming on a .json upload whose parsed top level is a scalar (e.g. 42, \"text\"), or an unsupported container shape not matched by the parser's known cases.","commonSituations":"Uploading a JSON file that is a single number/string; files exported with an envelope object like {\"items\": [...]} that the reader does not unwrap; corrupted or hand-edited JSON exports.","solutions":["Wrap the content as a top-level JSON array of objects, e.g. [{\"data\": {...}}]","Unwrap any envelope key so the file's root is the tasks array itself","Validate the file parses to an array or object before uploading"],"exampleFix":"// before (tasks.json)\n{\"items\": [{\"text\": \"a\"}]}\n// after\n[{\"data\": {\"text\": \"a\"}}]","handlingStrategy":"validation","validationCode":"import json\nwith open('tasks.json', encoding='utf8') as f:\n    root = json.load(f)\nif not isinstance(root, (list, dict)):\n    raise ValueError(\"Top level must be an array or object\")\nif isinstance(root, dict):\n    root = [root]\nassert all(isinstance(t, (dict,)) for t in root), \"All tasks must be objects\"","typeGuard":"def is_streamable_json_root(value):\n    if isinstance(value, list):\n        return all(isinstance(t, dict) for t in value)\n    return isinstance(value, dict)","tryCatchPattern":"try:\n    for batch in fu.read_tasks_streaming():\n        process(batch)\nexcept ValidationError as e:\n    logger.error(\"Streaming import rejected file: %s\", e)","preventionTips":["Keep the file's root as a JSON array of objects","Avoid envelope objects like {\"items\": [...]}","Lint the JSON with python -m json.tool before import"],"tags":["json","validation","streaming","data-import"],"backgroundTag":"json-schema-validation-failed","analyzedSha":"0b49e9b53917880baf1dd85d574fe5541a9aafb2","analyzedAt":"2026-08-29T00:39:52.578Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}