sgl-project/sglang · error · RuntimeError

Mesh generation failed: surface extraction returned None. Th

Error message

Mesh generation failed: surface extraction returned None. The surface level may be outside the volume data range.

What it means

During mesh extraction the marching-cubes style surface extraction returned None, meaning the extracted isosurface (at the configured level value) does not intersect the volume data range — the SDF/occupancy field never crosses the surface threshold. When paint_enable is off this is fatal; with painting enabled the batch is merely flagged _mesh_failed and continues.

Source

Thrown at python/sglang/multimodal_gen/runtime/pipelines_core/stages/model_specific_stages/hunyuan3d/shape.py:570

        return output_path + ".obj", output_path + ".obj"

    def forward(self, batch: Req, server_args: ServerArgs) -> Req | OutputBatch:
        mesh_outputs = batch.extra["shape_meshes"]
        mesh = mesh_outputs[0] if isinstance(mesh_outputs, list) else mesh_outputs
        if isinstance(mesh, list):
            mesh = mesh[0]

        if mesh is None:
            if batch.is_warmup:
                logger.info(
                    "Skipping mesh export during warmup "
                    "(surface extraction returned None)"
                )
                batch.extra["_mesh_failed"] = True
                if self.config.paint_enable:
                    return batch
                return OutputBatch(output_file_paths=[], metrics=batch.metrics)
            raise RuntimeError(
                "Mesh generation failed: surface extraction returned None. "
                "The surface level may be outside the volume data range."
            )

        if batch.is_warmup:
            if self.config.paint_enable:
                return batch
            return OutputBatch(output_file_paths=[], metrics=batch.metrics)

        obj_path, return_path = self._get_output_paths(batch)
        output_dir = os.path.dirname(obj_path)
        if output_dir:
            os.makedirs(output_dir, exist_ok=True)
        mesh.export(obj_path)

        batch.extra["shape_obj_path"] = obj_path
        batch.extra["shape_return_path"] = return_path

View on GitHub (pinned to 0132848349)

Solutions

  1. Increase num_inference_steps and use recommended guidance settings so the volume has a meaningful isosurface
  2. Check the volume tensor for NaNs or constant values (log vol.min()/vol.max()) and verify checkpoint/dtype compatibility; switch to fp32 if NaNs appear
  3. If using painting, set paint_enable=True so failure degrades gracefully and inspect batch.extra['_mesh_failed']
  4. Verify latent_shape matches the model config so the decoded volume has expected range

Example fix

# before
run = stage.forward(batch, server_args)  # num_inference_steps=4

# after
batch.num_inference_steps = 50  # recommended
batch.extra["shape_guidance"] = default_guidance
run = stage.forward(batch, server_args)
Defensive patterns

Strategy: fallback

Validate before calling

vol = decoded_volume
if torch.isnan(vol).any() or vol.min() == vol.max():
    raise ValueError("degenerate volume; increase steps / check weights")

Try / catch

try:
    out = stage.forward(batch, server_args)
except RuntimeError as e:
    if "surface extraction returned None" in str(e):
        batch.num_inference_steps = max(batch.num_inference_steps * 2, 50)
        out = stage.forward(batch, server_args)  # retry once
    else:
        raise

Prevention

When it happens

Trigger: num_inference_steps too low or guidance misconfigured so the denoised volume is degenerate; the surface level constant lies outside [min, max] of the produced volume; NaNs/constant volumes from a broken checkpoint or dtype issues collapse the field to a single value.

Common situations: Very few denoising steps producing a blob with no zero-crossing; fp16/bf16 overflow producing NaN volumes; wrong model weights or a mismatched latent shape; extreme guidance_scale values saturating the occupancy field.

Related errors


AI-assisted analysis of sgl-project/sglang@0132848349 (2026-08-28). Data as JSON: /api/errors/5d11f7a5820dba01. Report an issue: GitHub.