{"record":{"id":"c275169fdb64d4ff","repo":"sgl-project/sglang","slug":"failed-to-process-image-source-str-e-c27516","errorCode":null,"errorMessage":"Failed to process image source: {str(e)}","messagePattern":"Failed to process image source: (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"python/sglang/multimodal_gen/runtime/entrypoints/openai/mesh_api.py","lineNumber":170,"sourceCode":"        urls = url or url_array\n        image_list = merge_image_input_list(images, urls)\n\n        if not image_list:\n            raise HTTPException(\n                status_code=422,\n                detail=\"Field 'image' or 'url' is required for mesh generation\",\n            )\n\n        uploads_dir = os.path.join(\"outputs\", \"uploads\")\n        os.makedirs(uploads_dir, exist_ok=True)\n        img = image_list[0]\n        filename = img.filename if hasattr(img, \"filename\") else \"input_image\"\n        try:\n            input_path = await save_image_to_path(\n                img, os.path.join(uploads_dir, f\"{request_id}_{filename}\")\n            )\n        except Exception as e:\n            raise HTTPException(\n                status_code=400, detail=f\"Failed to process image source: {str(e)}\"\n            )\n\n        req = MeshGenerationsRequest(\n            prompt=prompt or \"generate 3d mesh\",\n            model=model,\n            seed=seed,\n            generator_device=generator_device,\n            num_inference_steps=num_inference_steps,\n            negative_prompt=negative_prompt,\n            output_format=output_format,\n            **(\n                {\"guidance_scale\": guidance_scale} if guidance_scale is not None else {}\n            ),\n        )\n    else:\n        try:\n            body = await request.json()","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/multimodal_gen/runtime/entrypoints/openai/mesh_api.py#L152-L188","documentation":"Raised by the mesh generation endpoint when saving the uploaded image to the server's uploads directory fails. The endpoint wraps save_image_to_path in a try/except and converts any exception (I/O error, invalid file object, unwritable directory) into an HTTP 400 with the underlying message.","triggerScenarios":"POST to the mesh generations endpoint with a multipart image that cannot be read/saved: corrupted UploadFile stream, missing uploads directory, or filesystem permission errors on the server.","commonSituations":"Server container running as non-root without write access to the uploads dir; client sending a non-file field where an image is expected; disk full.","solutions":["Verify the uploaded file is a valid image (open it client-side before sending)","Check the server's uploads directory exists and is writable by the server process","Retry with a smaller/standard format (PNG/JPEG) image to rule out decode issues"],"exampleFix":"// before\nfiles = {\"image\": (\"mesh.txt\", open(\"mesh.txt\",\"rb\"), \"text/plain\")}\n// after\nfiles = {\"image\": (\"input.png\", open(\"input.png\",\"rb\"), \"image/png\")}","handlingStrategy":"try-catch","validationCode":"from PIL import Image\nimg = Image.open(path); img.verify()  # raises if not a valid image","typeGuard":null,"tryCatchPattern":"try:\n    resp = await client.post('/v1/mesh/generations', files=files)\nexcept httpx.HTTPStatusError as e:\n    if e.response.status_code == 400 and 'image source' in e.response.text:\n        # re-encode image and retry once\n        ...","preventionTips":["Validate images client-side before upload","Ensure server uploads dir is writable in deployment"],"tags":["http","upload","mesh-generation","client-error"],"backgroundTag":"file-upload-failed","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}