{"record":{"id":"16b566f7c885b3e7","repo":"calesthio/OpenMontage","slug":"missing-three-js-world-templates-join-missi","errorCode":null,"errorMessage":"Missing Three.js world templates: {', '.join(missing)}","messagePattern":"Missing Three\\.js world templates: (.+?)","errorType":"exception","errorClass":"FileNotFoundError","httpStatus":null,"severity":"critical","filePath":"tools/graphics/threejs_world.py","lineNumber":645,"sourceCode":"\n    @staticmethod\n    def _write_workspace(\n        *,\n        workspace: Path,\n        spec: dict[str, Any],\n        report: dict[str, Any],\n        duration: float,\n        width: int,\n        height: int,\n        render_mode: str,\n        quality_tier: str,\n        catalog_paths: list[Path],\n    ) -> list[str]:\n        template_dir = Path(__file__).resolve().parent / \"templates\" / \"threejs_world\"\n        required = [\"index.html\", \"world.css\", \"world-runtime.js\"]\n        missing = [name for name in required if not (template_dir / name).is_file()]\n        if missing:\n            raise FileNotFoundError(f\"Missing Three.js world templates: {', '.join(missing)}\")\n\n        workspace.mkdir(parents=True, exist_ok=True)\n        (workspace / \"assets\").mkdir(exist_ok=True)\n        (workspace / \"renders\").mkdir(exist_ok=True)\n\n        catalog_index: dict[str, Any] = {\"version\": \"1.0\", \"catalogs\": []}\n        model_root = workspace / \"assets\" / \"models\"\n        model_root.mkdir(parents=True, exist_ok=True)\n        for catalog_path in catalog_paths:\n            manifest_path = catalog_path / \"catalog-manifest.json\"\n            manifest = json.loads(manifest_path.read_text(encoding=\"utf-8\"))\n            catalog_id = str(manifest[\"catalog_id\"])\n            target = model_root / catalog_id\n            source = catalog_path / \"source\"\n            if target.exists():\n                shutil.rmtree(target)\n            shutil.copytree(source, target)\n            copied = copy.deepcopy(manifest)","sourceCodeStart":627,"sourceCodeEnd":663,"githubUrl":"https://github.com/calesthio/OpenMontage/blob/95e1c3d0ab93482159818560f6a8c8e866b9139f/tools/graphics/threejs_world.py#L627-L663","documentation":"Raised by the Three.js world builder when one or more of the bundled runtime templates — index.html, world.css, world-runtime.js — are missing from tools/graphics/templates/threejs_world/ next to threejs_world.py. These templates are the generated world's scaffold; without them the workspace cannot be assembled, so the tool fails fast with the exact missing names.","triggerScenarios":"Partial install or packaging of OpenMontage that shipped threejs_world.py but not its templates directory; templates deleted or moved during a refactor; running from a copied source tree that skipped non-Python files.","commonSituations":"pip install from a broken sdist/wheel; Docker image built with .dockerignore excluding template dirs; git sparse-checkout missing those paths.","solutions":["Check the exception message for the exact missing file names","Restore/reinstall the package so tools/graphics/templates/threejs_world/ contains all three files","If packaging, ensure non-Python data files are included (package_data / MANIFEST.in)","Verify with: ls tools/graphics/templates/threejs_world/"],"exampleFix":"# pyproject.toml (before: templates excluded)\n# after\n[tool.setuptools.package-data]\n\"tools.graphics\" = [\"templates/threejs_world/*\"]","handlingStrategy":"validation","validationCode":"from pathlib import Path\nrequired = [\"index.html\", \"world.css\", \"world-runtime.js\"]\ntdir = Path(tool_dir) / \"templates\" / \"threejs_world\"\nmissing = [n for n in required if not (tdir / n).is_file()]\nassert not missing, f\"templates missing: {missing}\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Include template dirs in package-data/wheel builds and test the wheel","Add a CI smoke test that instantiates the world builder","Verify installs with a file-presence check after deployment"],"tags":["threejs","packaging","missing-files","installation"],"backgroundTag":null,"analyzedSha":"95e1c3d0ab93482159818560f6a8c8e866b9139f","analyzedAt":"2026-08-15T06:31:20.014Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}