{"record":{"id":"7e01f19ea571211c","repo":"odysseus-dev/odysseus","slug":"invalid-box-format","errorCode":null,"errorMessage":"Invalid box format","messagePattern":"Invalid box format","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"warning","filePath":"routes/gallery/gallery_routes.py","lineNumber":1884,"sourceCode":"        kwargs: Dict[str, Any] = {\"return_tensors\": \"pt\"}\n        input_points = []\n        if points:\n            input_labels = []\n            for p in points:\n                try:\n                    input_points.append([float(p[\"x\"]), float(p[\"y\"])])\n                    input_labels.append(int(p.get(\"label\", 1)))\n                except Exception as exc:\n                    raise HTTPException(400, \"Invalid point format\") from exc\n            kwargs[\"input_points\"] = [input_points]\n            kwargs[\"input_labels\"] = [input_labels]\n        if box:\n            if not isinstance(box, list) or len(box) != 4:\n                raise HTTPException(400, \"Box must be [x1, y1, x2, y2]\")\n            try:\n                kwargs[\"input_boxes\"] = [[[float(v) for v in box]]]\n            except Exception as exc:\n                raise HTTPException(400, \"Invalid box format\") from exc\n\n        try:\n            inputs = processor(image, **kwargs)\n            model_inputs = _model_inputs_to_device(inputs, device, torch)\n            with torch.no_grad():\n                outputs = model(**model_inputs)\n            masks = processor.image_processor.post_process_masks(\n                outputs.pred_masks.detach().cpu(),\n                inputs[\"original_sizes\"].detach().cpu(),\n                inputs[\"reshaped_input_sizes\"].detach().cpu(),\n            )\n            mask_tensor = masks[0]\n            while getattr(mask_tensor, \"ndim\", 0) > 3:\n                mask_tensor = mask_tensor[0]\n            if getattr(mask_tensor, \"ndim\", 0) == 3:\n                scores = outputs.iou_scores.detach().cpu()[0]\n                while getattr(scores, \"ndim\", 0) > 1:\n                    scores = scores[0]","sourceCodeStart":1866,"sourceCodeEnd":1902,"githubUrl":"https://github.com/odysseus-dev/odysseus/blob/f9235ebbf13f693a6fd29ce70b097f6ec83705bf/routes/gallery/gallery_routes.py#L1866-L1902","documentation":"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.","triggerScenarios":"POST with box=[\"10\", null, 110, 220], box=[[10], 20, 110, 220], or box containing NaN-like strings.","commonSituations":"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.","solutions":["Coerce all four values to numbers before sending: [Number(x1), Number(y1), Number(x2), Number(y2)]","Guard against null/undefined coordinates and re-run detection if any are missing","Validate with a client-side schema (zod/pydantic) requiring number[4]"],"exampleFix":"// before\nbox: [x1, y1 ?? null, x2, y2]\n\n// after\nconst box = [x1, y1, x2, y2].map(Number);\nif (box.some(v => !Number.isFinite(v))) throw new Error('bad box');","handlingStrategy":"validation","validationCode":"def coerce_box(raw) -> list:\n    if not (isinstance(raw, list) and len(raw) == 4):\n        raise ValueError('box must have 4 elements')\n    box = [float(v) for v in raw]  # raises on None/'abc'/nested\n    return box","typeGuard":"function isFiniteBox(v: unknown): v is [number, number, number, number] {\n  return Array.isArray(v) && v.length === 4\n    && v.every(n => typeof n !== 'object' && n !== null && Number.isFinite(Number(n)));\n}","tryCatchPattern":"try:\n    box = coerce_box(body['box'])\nexcept (TypeError, ValueError):\n    return user_error('re-draw the selection box')  # instead of surfacing the 400 raw","preventionTips":["Map every coordinate through Number() and assert Number.isFinite before the request","Reject null/undefined coordinates at the source (re-run detection when a bbox component is missing)","Validate request payloads with a schema (zod/pydantic) in integration tests so type drift is caught in CI"],"tags":["http-400","validation","bounding-box","type-coercion","sam"],"backgroundTag":null,"analyzedSha":"f9235ebbf13f693a6fd29ce70b097f6ec83705bf","analyzedAt":"2026-08-14T21:47:48.359Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}