diff --git a/python/mujoco/codegen/generate_spec_bindings.py b/python/mujoco/codegen/generate_spec_bindings.py index 4dd24eea..5e0d68ae 100644 --- a/python/mujoco/codegen/generate_spec_bindings.py +++ b/python/mujoco/codegen/generate_spec_bindings.py @@ -841,7 +841,9 @@ def generate_add() -> None: code += """\n auto set_name = [](raw::MjsElement* el, const std::optional& name) { if (name.has_value()) { - mjs_setName(el, name->c_str()); + if (mjs_setName(el, name->c_str())) { + throw pybind11::value_error(mjs_getError(mjs_getSpec(el))); + } } }; """ diff --git a/python/mujoco/specs_test.py b/python/mujoco/specs_test.py index 0d25c838..c5976e3b 100644 --- a/python/mujoco/specs_test.py +++ b/python/mujoco/specs_test.py @@ -970,6 +970,26 @@ class SpecsTest(absltest.TestCase): ): spec.add_material().name = 'yellow' + def test_duplicate_name_error_when_adding_specs_with_kwargs(self): + spec = mujoco.MjSpec() + body = spec.worldbody.add_body(name='body') + body.add_geom( + type=mujoco.mjtGeom.mjGEOM_BOX, size=[0.1, 1, 1], name='dup' + ) + with self.assertRaisesRegex( + ValueError, "Error: repeated name 'dup' in geom" + ): + body.add_geom( + type=mujoco.mjtGeom.mjGEOM_BOX, size=[1, 0.1, 1], name='dup' + ) + + spec2 = mujoco.MjSpec() + spec2.add_material(name='yellow') + with self.assertRaisesRegex( + ValueError, "Error: repeated name 'yellow' in material" + ): + spec2.add_material(name='yellow') + def test_delete_unused_plugin(self): spec = mujoco.MjSpec.from_string("""