unslothai/unsloth · error · HTTPException

file_ids must not be empty

Error message

file_ids must not be empty

What it means

HTTP 400 raised at the top of POST /seed/inspect-upload when payload.file_ids is present (not None) but is an empty list. The API treats an explicit empty list as a malformed request — omit the field entirely if there is nothing to inspect.

Source

Thrown at studio/backend/routes/data_recipe/seed.py:624

        shutil.rmtree(block_dir)
    except OSError as exc:
        raise log_and_http_error(
            exc,
            500,
            "failed to delete uploaded files",
            event = "data_recipe.seed.unstructured_block_delete_failed",
            log = logger,
        ) from exc
    if block_dir.exists():
        raise HTTPException(500, "failed to delete uploaded files")
    return {"status": "ok", "deleted": True}


@router.post("/seed/inspect-upload", response_model = SeedInspectResponse)
def inspect_seed_upload(payload: SeedInspectUploadRequest) -> SeedInspectResponse:
    if payload.file_ids is not None:
        if len(payload.file_ids) == 0:
            raise HTTPException(400, "file_ids must not be empty")
        _validate_safe_id(payload.block_id, "block_id")
        for fid in payload.file_ids:
            _validate_safe_id(fid, "file_id")
        preview_rows = _read_preview_rows_from_multi_files(
            block_id = payload.block_id,
            file_ids = payload.file_ids,
            file_names = payload.file_names,
            preview_size = payload.preview_size,
            chunk_size = payload.unstructured_chunk_size,
            chunk_overlap = payload.unstructured_chunk_overlap,
        )
        columns = ["chunk_text", "source_file"] if preview_rows else []
        resolved_paths = [
            str(UNSTRUCTURED_UPLOAD_ROOT / payload.block_id / f"{fid}.extracted.txt")
            for fid in payload.file_ids
        ]
        return SeedInspectResponse(
            dataset_name = "unstructured_seed",

View on GitHub (pinned to 203007d190)

Solutions

  1. Omit file_ids from the JSON body when no files are selected.
  2. Client-side: skip the inspect call entirely when the selection is empty.
  3. Type the request so file_ids is optional and only include it when len > 0.

Example fix

# before
body = {'block_id': bid, 'file_ids': selected_ids}  # may be []

# after
body = {'block_id': bid}
if selected_ids:
    body['file_ids'] = selected_ids
Defensive patterns

Strategy: validation

Validate before calling

const body = { block_id: blockId, preview_size: n };
if (fileIds.length > 0) body.file_ids = fileIds;
if (fileNames?.length > 0) body.file_names = fileNames;
inspectUpload(body);

Type guard

function hasInspectableFiles(ids?: string[]): ids is string[] {
  return Array.isArray(ids) && ids.length > 0;
}

Try / catch

On 400 'file_ids must not be empty', log a client bug (empty selection should never reach the wire), fix the request builder, and skip the call.

Prevention

When it happens

Trigger: POST /seed/inspect-upload with {"file_ids": [], ...}, typically because the frontend serialized an empty selection instead of leaving the field out or using the single-file local path.

Common situations: UI sends the multi-file branch unconditionally with whatever selection exists; empty selection submitted; default [] in a request-building function that never gets popped.

Related errors


AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15). Data as JSON: /api/errors/a369b6090379fb94. Report an issue: GitHub.