#505·infinigen

room_walls() crashes with TypeError for wall materials without **kwargs

Author: ericdriggsCreated Jun 27, 2026Updated Jun 27, 2026
Labelsbug

Describe the bug

room_walls() in infinigen/core/constraints/example_solver/room/decorate.py passes tile-specific kwargs (vertical, alternating, shape) to all wall material generators unconditionally. Five material classes have def generate(self) with no **kwargs, causing a TypeError crash:

  • Concrete — crashes
  • Ceramic — crashes
  • MarbleRegular — crashes
  • MarbleVoronoi — crashes
  • Brick — already special-cased on line 227, so does not crash

The bug is on line 219-229:

python
kwargs = dict(vertical=True, alternating=False, shape=shape)
# ...
if wall_fn.__class__.__name__ == "Brick":
    kwargs = {}
surface.assign_material(rooms__, wall_fn(**kwargs))

Only Brick is excluded. When Concrete, Ceramic, MarbleRegular, or MarbleVoronoi is selected as a wall material, the call wall_fn(**kwargs) raises:

TypeError: Concrete.generate() got an unexpected keyword argument 'vertical'

This is hidden in default home scenes because room_wall_fns maps home room types to material sets that heavily favor Tile and Plaster (which accept **kwargs). But the defaultdict fallback (material_assignments.wall) includes Concrete and other non-kwargs materials, so any room type not in room_wall_fns can trigger the crash.

Failing test

This test reproduces the bug without Blender — it calls generate(**wall_kwargs) on each material, the same code path room_walls() takes:

python
import pytest

from infinigen.assets.materials.ceramic.brick import Brick
from infinigen.assets.materials.ceramic.ceramic import Ceramic
from infinigen.assets.materials.ceramic.concrete import Concrete
from infinigen.assets.materials.ceramic.marble_regular import MarbleRegular
from infinigen.assets.materials.ceramic.marble_voronoi import MarbleVoronoi
from infinigen.assets.materials.ceramic.plaster import Plaster
from infinigen.assets.materials.ceramic.tile import Tile

WALL_KWARGS = dict(vertical=True, alternating=False, shape="square")


@pytest.mark.parametrize(
    "material_cls",
    [Brick, Ceramic, Concrete, MarbleRegular, MarbleVoronoi, Plaster, Tile],
    ids=lambda c: c.__name__,
)
def test_room_walls_kwargs_crash(material_cls):
    """Calling material.generate(**wall_kwargs) must not raise TypeError."""
    mat = material_cls()
    try:
        mat.generate(**WALL_KWARGS)
    except TypeError as e:
        if "unexpected keyword argument" in str(e):
            pytest.fail(
                f"{material_cls.__name__}.generate() rejects kwargs that "
                f"room_walls() passes unconditionally: {e}"
            )
        raise

Result: 5 FAILED (Brick, Ceramic, Concrete, MarbleRegular, MarbleVoronoi), 2 passed (Plaster, Tile).

Steps to Reproduce

What version of the code were you using?

05a09759 Update Installation.md with git submodule instructions (latest main as of 2026-06-26)

What command did you run?

Any indoor generation with a room type not explicitly listed in room_wall_fns (line 138 of decorate.py). For example, generating a scene with custom room types that fall through to the defaultdict default:

bash
python -m pytest tests/solver/test_wall_material_kwargs.py -v

Or trigger it at runtime by generating a non-home scene where Concrete gets selected as a wall material.

What are your FULL output logs?

Partial logs — full runtime output was lost due to process termination. The relevant traceback and test output are below.

Unit test output:

FAILED tests/solver/test_wall_material_kwargs.py::test_room_walls_kwargs_crash[Brick]
FAILED tests/solver/test_wall_material_kwargs.py::test_room_walls_kwargs_crash[Ceramic]
FAILED tests/solver/test_wall_material_kwargs.py::test_room_walls_kwargs_crash[Concrete]
FAILED tests/solver/test_wall_material_kwargs.py::test_room_walls_kwargs_crash[MarbleRegular]
FAILED tests/solver/test_wall_material_kwargs.py::test_room_walls_kwargs_crash[MarbleVoronoi]
==================== 5 failed, 2 passed in 1.76s ====================

Runtime crash traceback:

[09:32:25.749] [logging] [INFO] | [MAIN TOTAL] failed with <class 'TypeError'>
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/Users/ericdriggs/github/princeton-vi/infinigen/infinigen_examples/generate_indoors.py", line 605, in <module>
    main(args)
  File "/Users/ericdriggs/github/princeton-vi/infinigen/infinigen_examples/generate_indoors.py", line 541, in main
    execute_tasks.main(
  File "/Users/ericdriggs/github/princeton-vi/infinigen/infinigen/core/execute_tasks.py", line 365, in main
    execute_tasks(
  File "/Users/ericdriggs/miniconda3/envs/infinigen/lib/python3.11/site-packages/gin/config.py", line 1605, in gin_wrapper
    utils.augment_exception_message_and_reraise(e, err_str)
  File "/Users/ericdriggs/miniconda3/envs/infinigen/lib/python3.11/site-packages/gin/utils.py", line 41, in augment_exception_message_and_reraise
    raise proxy.with_traceback(exception.__traceback__) from None
  File "/Users/ericdriggs/miniconda3/envs/infinigen/lib/python3.11/site-packages/gin/config.py", line 1582, in gin_wrapper
    return fn(*new_args, **new_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/ericdriggs/github/princeton-vi/infinigen/infinigen/core/execute_tasks.py", line 244, in execute_tasks
    info = compose_scene_func(output_folder, scene_seed)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/ericdriggs/miniconda3/envs/infinigen/lib/python3.11/site-packages/gin/config.py", line 1605, in gin_wrapper
    utils.augment_exception_message_and_reraise(e, err_str)
  File "/Users/ericdriggs/miniconda3/envs/infinigen/lib/python3.11/site-packages/gin/utils.py", line 41, in augment_exception_message_and_reraise
    raise proxy.with_traceback(exception.__traceback__) from None
  File "/Users/ericdriggs/miniconda3/envs/infinigen/lib/python3.11/site-packages/gin/config.py", line 1582, in gin_wrapper
    return fn(*new_args, **new_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/ericdriggs/github/princeton-vi/infinigen/infinigen_examples/generate_indoors.py", line 407, in compose_indoors
    p.run_stage(
  File "/Users/ericdriggs/github/princeton-vi/infinigen/infinigen/core/util/pipeline.py", line 89, in run_stage
    ret = fn(*args, **kwargs)
          ^^^^^^^^^^^^^^^^^^^
  File "/Users/ericdriggs/github/princeton-vi/infinigen/infinigen/core/constraints/example_solver/room/decorate.py", line 229, in room_walls
    surface.assign_material(rooms__, wall_fn(**kwargs))
                                     ^^^^^^^^^^^^^^^^^
TypeError: Concrete.generate() got an unexpected keyword argument 'vertical'
  In call to configurable 'compose_indoors' (<function compose_indoors at 0x317952480>)
  In call to configurable 'execute_tasks' (<function execute_tasks at 0x3175413a0>)

Platform

  • OS & OS Version: macOS Darwin 25.0.0 (arm64)
  • GPU: Apple M-series (Metal)
  • RAM: 16 GB

Additional context

Suggested fix

Check whether generate() accepts **kwargs before passing them:

python
import inspect
sig = inspect.signature(wall_fn.generate)
has_var_keyword = any(
    p.kind == inspect.Parameter.VAR_KEYWORD
    for p in sig.parameters.values()
)
surface.assign_material(
    rooms__, wall_fn(**(kwargs if has_var_keyword else {}))
)

Alternatively, add **kwargs to all material generate() methods for forward compatibility.