odysseus-dev/odysseus · warning · HTTPException

Invalid box format

Error message

Invalid box format

What it means

HTTP 400 raised when the box passes the shape check (list of length 4) but one of its elements cannot be converted with float() — e.g. a string like 'abc', None, or a nested list. Distinct from 603, which catches wrong shape; this catches wrong element types.

Source

Thrown at routes/gallery/gallery_routes.py:1884

        kwargs: Dict[str, Any] = {"return_tensors": "pt"}
        input_points = []
        if points:
            input_labels = []
            for p in points:
                try:
                    input_points.append([float(p["x"]), float(p["y"])])
                    input_labels.append(int(p.get("label", 1)))
                except Exception as exc:
                    raise HTTPException(400, "Invalid point format") from exc
            kwargs["input_points"] = [input_points]
            kwargs["input_labels"] = [input_labels]
        if box:
            if not isinstance(box, list) or len(box) != 4:
                raise HTTPException(400, "Box must be [x1, y1, x2, y2]")
            try:
                kwargs["input_boxes"] = [[[float(v) for v in box]]]
            except Exception as exc:
                raise HTTPException(400, "Invalid box format") from exc

        try:
            inputs = processor(image, **kwargs)
            model_inputs = _model_inputs_to_device(inputs, device, torch)
            with torch.no_grad():
                outputs = model(**model_inputs)
            masks = processor.image_processor.post_process_masks(
                outputs.pred_masks.detach().cpu(),
                inputs["original_sizes"].detach().cpu(),
                inputs["reshaped_input_sizes"].detach().cpu(),
            )
            mask_tensor = masks[0]
            while getattr(mask_tensor, "ndim", 0) > 3:
                mask_tensor = mask_tensor[0]
            if getattr(mask_tensor, "ndim", 0) == 3:
                scores = outputs.iou_scores.detach().cpu()[0]
                while getattr(scores, "ndim", 0) > 1:
                    scores = scores[0]

View on GitHub (pinned to f9235ebbf1)

Solutions

  1. Coerce all four values to numbers before sending: [Number(x1), Number(y1), Number(x2), Number(y2)]
  2. Guard against null/undefined coordinates and re-run detection if any are missing
  3. Validate with a client-side schema (zod/pydantic) requiring number[4]

Example fix

// before
box: [x1, y1 ?? null, x2, y2]

// after
const box = [x1, y1, x2, y2].map(Number);
if (box.some(v => !Number.isFinite(v))) throw new Error('bad box');
Defensive patterns

Strategy: validation

Validate before calling

def coerce_box(raw) -> list:
    if not (isinstance(raw, list) and len(raw) == 4):
        raise ValueError('box must have 4 elements')
    box = [float(v) for v in raw]  # raises on None/'abc'/nested
    return box

Type guard

function isFiniteBox(v: unknown): v is [number, number, number, number] {
  return Array.isArray(v) && v.length === 4
    && v.every(n => typeof n !== 'object' && n !== null && Number.isFinite(Number(n)));
}

Try / catch

try:
    box = coerce_box(body['box'])
except (TypeError, ValueError):
    return user_error('re-draw the selection box')  # instead of surfacing the 400 raw

Prevention

When it happens

Trigger: POST with box=["10", null, 110, 220], box=[[10], 20, 110, 220], or box containing NaN-like strings.

Common situations: Box parsed from a form field or URL param left as strings with a missing value; detection library returning None for a failed coordinate; client spreading an object with undefined members.

Related errors


AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14). Data as JSON: /api/errors/7e01f19ea571211c. Report an issue: GitHub.