{"record":{"id":"3255a9a17177d436","repo":"HumanSignal/label-studio","slug":"file-upload-ids-parameter-must-be-a-list-of-inte","errorCode":null,"errorMessage":"\"file_upload_ids\" parameter must be a list of integers","messagePattern":"\"file_upload_ids\" parameter must be a list of integers","errorType":"exception","errorClass":"ValueError","httpStatus":500,"severity":"error","filePath":"label_studio/data_import/api.py","lineNumber":863,"sourceCode":"            return FileUpload.objects.filter(project_id=project.id, user=self.request.user)\n\n        # If requested in regular import, only queried IDs are returned to avoid showing previously imported\n        ids = json.loads(self.request.query_params.get('ids', '[]'))\n        logger.debug(f'File Upload IDs found: {ids}')\n        return FileUpload.objects.filter(project_id=project.id, id__in=ids, user=self.request.user)\n\n    def get(self, request, *args, **kwargs):\n        return self.list(request, *args, **kwargs)\n\n    def delete(self, request, *args, **kwargs):\n        project = generics.get_object_or_404(Project.objects.for_user(self.request.user), pk=self.kwargs['pk'])\n        ids = self.request.data.get('file_upload_ids')\n        if ids is None:\n            deleted, _ = FileUpload.objects.filter(project=project).delete()\n        elif isinstance(ids, list):\n            deleted, _ = FileUpload.objects.filter(project=project, id__in=ids).delete()\n        else:\n            raise ValueError('\"file_upload_ids\" parameter must be a list of integers')\n        return Response({'deleted': deleted}, status=status.HTTP_200_OK)\n\n\n@method_decorator(\n    name='get',\n    decorator=extend_schema(\n        tags=['Import'],\n        summary='Get file upload',\n        description='Retrieve details about a specific uploaded file.',\n        extensions={\n            'x-fern-sdk-group-name': ['files'],\n            'x-fern-sdk-method-name': 'get',\n            'x-fern-audiences': ['public'],\n        },\n    ),\n)\n@method_decorator(\n    name='patch',","sourceCodeStart":845,"sourceCodeEnd":881,"githubUrl":"https://github.com/HumanSignal/label-studio/blob/0b49e9b53917880baf1dd85d574fe5541a9aafb2/label_studio/data_import/api.py#L845-L881","documentation":"The FileUpload delete endpoint accepts 'file_upload_ids' in the request body: None deletes ALL uploads for the project, a list deletes only those IDs, and any other type raises this plain ValueError. It is a Python ValueError, not DRF ValidationError, so it typically surfaces as a 500 rather than a structured 400.","triggerScenarios":"POST/DELETE to the file-upload delete endpoint (api.FileUploadListDelete) with body {'file_upload_ids': <non-list>} — e.g. a single integer 5, a string \"5\", a dict, or a comma-separated string — instead of a JSON array of integers.","commonSituations":"Client sending a single ID without wrapping it in a list; form-encoded bodies where lists get serialized as strings; scripts passing a tuple or a set; frontend JSON.stringify mistakes; dangerously sending null/omitting the key and wiping all uploads instead (the None branch is total deletion).","solutions":["Send file_upload_ids as a JSON array of integers: {\"file_upload_ids\": [1, 2, 3]}","If deleting a single upload, still wrap it: [42], not 42","If you intended to delete everything, explicitly pass null / omit the key — review carefully, this deletes ALL project uploads","Handle the string case: convert a comma-separated string to a list of ints before sending","Report/handle the 500-style ValueError response in client error handling since it is not a structured 400"],"exampleFix":"// before\nrequests.post(url, headers=headers, json={\"file_upload_ids\": 42})\n// after\nrequests.post(url, headers=headers, json={\"file_upload_ids\": [42]})","handlingStrategy":"type-guard","validationCode":"ids = body.get('file_upload_ids')\nif ids is not None and not (isinstance(ids, list) and all(isinstance(i, int) for i in ids)):\n    raise ValueError('file_upload_ids must be a list of integers (or null to delete all)')","typeGuard":"def is_valid_upload_ids(v) -> bool:\n    return v is None or (isinstance(v, list) and all(isinstance(i, int) and not isinstance(i, bool) for i in v))","tryCatchPattern":"try:\n    resp = requests.post(delete_url, headers=H, json={'file_upload_ids': ids})\n    resp.raise_for_status()\nexcept requests.HTTPError as e:\n    if 'must be a list of integers' in e.response.text:\n        raise TypeError('Wrap the id in a list: {\"file_upload_ids\": [42]}')","preventionTips":["Always wrap single IDs in a list before sending","Confirm json= (not data=) is used so lists survive serialization","Be deliberate about null/omitted file_upload_ids: it deletes ALL project uploads","Reject bools and numeric strings client-side before sending"],"tags":["django","rest-framework","delete","type-error","api"],"backgroundTag":"wrong-parameter-type","analyzedSha":"0b49e9b53917880baf1dd85d574fe5541a9aafb2","analyzedAt":"2026-08-29T00:39:52.578Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}