{"record":{"id":"5d80ebc706141c87","repo":"Genesis-Embodied-AI/genesis-world","slug":"cannot-handle-soft-material-material-soft","errorCode":null,"errorMessage":"Cannot handle soft material {material_soft}","messagePattern":"Cannot handle soft material (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"genesis/engine/entities/hybrid_entity.py","lineNumber":152,"sourceCode":"            if isinstance(material_soft, gs.materials.MPM.Base):\n                part_soft_info = qd.types.struct(\n                    link_idx=gs.qd_int,\n                    geom_idx=gs.qd_int,\n                    trans_local_to_global=gs.qd_vec3,\n                    quat_local_to_global=gs.qd_vec4,\n                ).field(shape=(material_soft.n_groups,), needs_grad=False, layout=qd.Layout.SOA)\n                part_soft_info.link_idx.from_numpy(np.asarray(link_idcs, dtype=gs.np_int))\n                part_soft_info.geom_idx.from_numpy(np.asarray(geom_idcs, dtype=gs.np_int))\n                part_soft_info.trans_local_to_global.from_numpy(np.asarray(trans_local_to_global, dtype=gs.np_float))\n                part_soft_info.quat_local_to_global.from_numpy(np.asarray(quat_local_to_global, dtype=gs.np_float))\n\n                part_soft_init_positions = qd.field(dtype=gs.qd_vec3, shape=(part_soft.init_particles.shape[0],))\n                part_soft_init_positions.from_torch(gs.Tensor(part_soft.init_particles))\n\n                self._part_soft_info = part_soft_info\n                self._part_soft_init_positions = part_soft_init_positions\n            else:\n                raise ValueError(f\"Cannot handle soft material {material_soft}\")\n\n            # set coupling func\n            def wrap_func(func, before=False):\n                def wrapper(f):\n                    if before:\n                        self.update_soft_part(f)\n                    func(f)\n                    if not before:\n                        self.update_soft_part(f)\n\n                return wrapper\n\n            if isinstance(material_soft, gs.materials.MPM.Base):\n                # NOTE: coupling operating at particle level and here we modify post_coupling, i.e., update particle state after g2p\n                self._update_soft_part_at_pre_coupling = False\n                if self._update_soft_part_at_pre_coupling:\n                    part_soft.solver.substep_pre_coupling = wrap_func(\n                        part_soft.solver.substep_pre_coupling, before=True","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/Genesis-Embodied-AI/genesis-world/blob/56e4aa5d82bdb83f2e532e4cc364cb69527acb06/genesis/engine/entities/hybrid_entity.py#L134-L170","documentation":"When a hybrid entity sets up its soft part with explicit (non-default) coupling functions, the soft material attached to the soft particle system must be one of the recognized soft material classes (the branch handling `part_soft.init_particles`, e.g. Particle or similar MSM/soft materials). If `material_soft` is of any other type, the else branch raises this ValueError, echoing the material in the message.","triggerScenarios":"`scene.add_entity(HybridEntity(...))` with `use_default_coupling=False` and a soft material whose type is not one of the supported soft material classes (e.g. a rigid or unknown/custom material passed as the soft part).","commonSituations":"Mixing up the material arguments when constructing a hybrid entity (passing a RigidMaterial where the soft material is expected); passing a custom material subclass the coupler does not recognize.","solutions":["Pass a supported soft material class (e.g. gs.materials.Particle or the MSM/soft material used in the hybrid examples) as the soft material.","Check the hybrid examples for the exact material combination supported by HybridEntity and mirror it."],"exampleFix":"// not applicable - depends on supported soft material classes in the installed version","handlingStrategy":"type-guard","validationCode":"import genesis as gs\nsoft = gs.materials.Particle()\nif not isinstance(soft, tuple(SUPPORTED_SOFT_MATERIALS)):\n    raise TypeError(f\"Unsupported soft material: {type(soft).__name__}\")","typeGuard":"def is_supported_soft_material(material) -> bool:\n    import genesis as gs\n    return isinstance(material, (gs.materials.Particle,))  # extend per version's supported set","tryCatchPattern":"try:\n    entity = scene.add_entity(gs.entities.HybridEntity(morph=m, material=mat))\nexcept ValueError as e:\n    if \"Cannot handle soft material\" in str(e):\n        raise ValueError(f\"Bad soft material: {e}\") from e\n    raise","preventionTips":["Copy the material combination verbatim from a hybrid example first, then vary one thing at a time.","Re-check supported soft materials after upgrading Genesis."],"tags":["python","genesis","invalid-argument","hybrid-entity","material"],"backgroundTag":"unsupported-argument-value","analyzedSha":"56e4aa5d82bdb83f2e532e4cc364cb69527acb06","analyzedAt":"2026-08-28T15:15:07.922Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}