{"record":{"id":"252117a95e8f2d76","repo":"sgl-project/sglang","slug":"metal-shader-sources-is-empty-nothing-to-compile","errorCode":null,"errorMessage":"metal_shader_sources is empty; nothing to compile","messagePattern":"metal_shader_sources is empty; nothing to compile","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"python/sglang/kernels/aot/setup_metal.py","lineNumber":178,"sourceCode":"        metallib_path = generated_dir / metallib_name\n        metal_std = os.environ.get(\"SGL_METAL_STD\", \"metal3.1\")\n\n        ext_include_dirs = [Path(p) for p in (ext.include_dirs or [])]\n        host_includes = [\n            python_include,\n            nanobind_dir / \"include\",\n            nanobind_dir / \"ext\" / \"robin_map\" / \"include\",\n            mlx_include,\n            mlx_include / \"metal_cpp\",\n        ]\n        all_includes = ext_include_dirs + host_includes\n        include_args = [f\"-I{p}\" for p in all_includes]\n        # `xcrun metal` accepts `-I` for header search; reuse the project\n        # include dirs so shaders can include shared MSL headers.\n        metal_include_args = [f\"-I{p}\" for p in ext_include_dirs]\n\n        if not metal_shader_sources:\n            raise RuntimeError(\"metal_shader_sources is empty; nothing to compile\")\n\n        air_paths = []\n        for rel in metal_shader_sources:\n            metal_src = root / rel\n            if not metal_src.is_file():\n                raise RuntimeError(f\"metal shader source not found: {metal_src}\")\n            air_path = generated_dir / (metal_src.stem + \".air\")\n            self.spawn(\n                [\n                    \"xcrun\",\n                    \"-sdk\",\n                    \"macosx\",\n                    \"metal\",\n                    f\"-std={metal_std}\",\n                    *metal_flags,\n                    *metal_include_args,\n                    \"-c\",\n                    str(metal_src),","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/kernels/aot/setup_metal.py#L160-L196","documentation":"The Metal build step requires a non-empty list of .metal shader sources to compile. If metal_shader_sources resolves empty (nothing matched, or the extension was declared without shader files), it raises rather than producing an extension with no GPU code.","triggerScenarios":"Declaring a BuildMetalExtension-backed Extension whose sources include no .metal files, or glob patterns (e.g. csrc/**/*.metal) that match nothing because the checkout/layout changed.","commonSituations":"Repo restructures moving shader directories; typos in glob patterns; building a source tarball that excluded .metal files.","solutions":["Check the glob/source list used to build metal_shader_sources and verify the .metal files exist in the checkout","Run the build from the repository root (paths are resolved relative to the setup script)","Fix or remove the extension declaration if no shaders are intended"],"exampleFix":"# before\nmetal_shader_sources = sorted(glob('csrc/metal/*.metall'))\n# after\nmetal_shader_sources = sorted(glob('csrc/metal/*.metal'))\nassert metal_shader_sources, 'no metal shaders found'","handlingStrategy":"validation","validationCode":"assert metal_shader_sources, 'no .metal files matched'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Assert glob results in build scripts","Build from repo root"],"tags":["metal","build","empty-input","shader"],"backgroundTag":"empty-build-source-list","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}