affaan-m/ECC · error · RuntimeError

input changed during scene build

Error message

input changed during scene build

What it means

Integrity guard late in build: the mesh or grade.json hash no longer matches the value recorded at build start, meaning an input file was modified while the Blender scene was being built. The receipt would be invalid, so the build refuses.

Solutions

  1. Ensure inputs are stable while a build runs; re-run the build after the files settle
  2. Avoid regenerating the stylepack concurrently with a prop build
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at skills/taste-application/scripts/blender_prop.py:303 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/8bd4464f811f0540. Report an issue: GitHub.

Appendix: source

Thrown at skills/taste-application/scripts/blender_prop.py:303

        with tempfile.TemporaryDirectory(prefix=".taste-blender-", dir=out.parent) as temporary:
            staged = Path(temporary) / "scene.blend"
            bpy.ops.wm.save_as_mainfile(filepath=str(staged), check_existing=False, copy=True)
            if not staged.is_file() or staged.stat().st_size == 0:
                raise RuntimeError("Blender failed to save scene")
            validate_output(out)
            os.link(staged, out)
        print(f"[prop] scene -> {out}")

    if render_dir:
        validate_output(render_dir)
        render_dir.mkdir(parents=True, exist_ok=False)
        status = bpy.ops.render.render(animation=True)
        verify_render(status, render_dir, frames)
        print(f"[prop] frames -> {render_dir}")

    if receipt:
        if _sha256(mesh) != source_hash or (_sha256(grade) if grade.is_file() else None) != grade_hash:
            raise RuntimeError("input changed during scene build")
        payload = {
            "schema_version": 1, "blender_version": bpy.app.version_string,
            "source": {"path": str(mesh.absolute()), "sha256": source_hash},
            "grade": {"path": str(grade.absolute()), "sha256": grade_hash},
            "scene": {"meshes": [o.name for o in objs], "mesh_count": len(objs),
                      "materials": sorted({slot.material.name for o in objs for slot in o.material_slots if slot.material}),
                      "textures": [{"name": image.name, "packed": bool(image.packed_file)}
                                   for image in bpy.data.images if image.source == "FILE"],
                      "bounds": [list(mn), list(mx)], "dimensions": list(mx - mn),
                      "rim_colour": list(rim), "width": sc.render.resolution_x,
                      "height": sc.render.resolution_y, "fps": sc.render.fps / sc.render.fps_base,
                      "frame_start": sc.frame_start, "frame_end": sc.frame_end,
                      "view_transform": sc.view_settings.view_transform,
                      "render_engine": sc.render.engine, "render_filepath": sc.render.filepath},
            "output": {"path": str(out.absolute()), "sha256": _sha256(out), "bytes": out.stat().st_size},
            "saved": True, "rendered": render_dir is not None,
            "render_dir": str(render_dir.absolute()) if render_dir else None,
            "rendered_frame_count": frames if render_dir else 0,

View on GitHub (pinned to 8321021c54)