{"record":{"id":"6d726e48e5fd25a1","repo":"unslothai/unsloth","slug":"provide-either-content-base64-or-file-ids-not-bot","errorCode":null,"errorMessage":"Provide either content_base64 or file_ids, not both","messagePattern":"Provide either content_base64 or file_ids, not both","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"warning","filePath":"studio/backend/models/data_recipe.py","lineNumber":95,"sourceCode":"    # Legacy single-file flow (mutually exclusive with file_ids)\n    filename: str | None = None\n    content_base64: str | None = None\n    # Multi-file flow (mutually exclusive with content_base64)\n    block_id: str | None = None\n    file_ids: list[str] | None = None\n    file_names: list[str] | None = None\n    # Shared fields\n    preview_size: int = Field(default = 10, ge = 1, le = 50)\n    seed_source_type: str | None = None\n    unstructured_chunk_size: int | None = Field(default = None, ge = 1, le = 20000)\n    unstructured_chunk_overlap: int | None = Field(default = None, ge = 0, le = 20000)\n\n    @model_validator(mode = \"after\")\n    def _check_mutual_exclusivity(self) -> \"SeedInspectUploadRequest\":\n        has_legacy = self.content_base64 is not None\n        has_multi = self.file_ids is not None\n        if has_legacy and has_multi:\n            raise ValueError(\"Provide either content_base64 or file_ids, not both\")\n        if not has_legacy and not has_multi:\n            raise ValueError(\"Provide either content_base64 or file_ids\")\n        if has_multi:\n            if len(self.file_ids) == 0:\n                raise ValueError(\"file_ids must not be empty\")\n            if not self.block_id:\n                raise ValueError(\"block_id is required when using file_ids\")\n            if self.file_names is None or len(self.file_ids) != len(self.file_names):\n                raise ValueError(\"file_names must be provided and same length as file_ids\")\n        if has_legacy:\n            if not self.filename:\n                raise ValueError(\"filename is required when using content_base64\")\n        return self\n\n\nclass SeedInspectResponse(BaseModel):\n    dataset_name: str\n    resolved_path: str","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/models/data_recipe.py#L77-L113","documentation":"Pydantic model_validator error on SeedInspectUploadRequest when the payload sets BOTH content_base64 (legacy single-file inline upload) and file_ids (multi-file upload). The two upload modes are mutually exclusive; the validator runs after field validation and rejects the request with a 422 before any handler logic executes.","triggerScenarios":"POSTing to the seed-inspect endpoint with a JSON body containing both 'content_base64' and 'file_ids' keys, e.g. a client that added multi-file support while still sending the legacy inline field for backward compatibility.","commonSituations":"Frontend migration from single-file to multi-file upload where the old field is not removed; API clients written defensively that populate every optional field; contract tests that send all fields.","solutions":["Remove one of the two fields from the request body — send either {\"content_base64\": ..., \"filename\": ...} or {\"file_ids\": [...], \"file_names\": [...], \"block_id\": ...}.","Update the client's request builder so the two modes are separate code paths that never merge payloads.","Check the response's 422 detail to confirm which validator fired."],"exampleFix":"// before\n{\n  \"content_base64\": \"...\",\n  \"filename\": \"a.jsonl\",\n  \"file_ids\": [\"f1\"]\n}\n// after\n{\n  \"file_ids\": [\"f1\"],\n  \"file_names\": [\"a.jsonl\"],\n  \"block_id\": \"block-1\"\n}","handlingStrategy":"validation","validationCode":"def build_seed_inspect_body(content_base64=None, filename=None,\n                                  file_ids=None, file_names=None, block_id=None):\n    has_legacy = content_base64 is not None\n    has_multi = file_ids is not None\n    assert not (has_legacy and has_multi), \"mutually exclusive upload modes\"\n    assert has_legacy or has_multi, \"one upload mode required\"\n    return ({\\\"content_base64\\\": content_base64, \\\"filename\\\": filename}\n            if has_legacy\n            else {\"file_ids\": file_ids, \"file_names\": file_names, \"block_id\": block_id})","typeGuard":"def is_single_seed_payload(p: dict) -> bool:\n    return (\"content_base64\" in p) != (\"file_ids\" in p)","tryCatchPattern":"try:\n    resp = client.post(\"/api/data/seed/inspect\", json=payload)\nexcept ValidationError:  # httpx/pydantic client-side\n    raise\nif resp.status_code == 422:\n    detail = resp.json()[\"detail\"]\n    # surface msg to the upload UI instead of retrying blindly","preventionTips":["Model the two upload modes as separate types in the client; never merge their fields.","Before submit, assert exactly one of content_base64 / file_ids is present.","Surfacing the 422 detail string in the UI pinpoints which constraint failed."],"tags":["validation","pydantic","api","http-422","upload"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}