{"record":{"id":"b759d904b88269bc","repo":"sgl-project/sglang","slug":"invalid-rust-extension-build-mode-mode-r-expect","errorCode":null,"errorMessage":"invalid Rust extension build mode {mode!r}; expected auto, never, or force","messagePattern":"invalid Rust extension build mode (.+?); expected auto, never, or force","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/rust_extensions/loader.py","lineNumber":88,"sourceCode":"    cache_dir: Path | None = None,\n    workspace: Path | None = None,\n) -> ModuleType:\n    \"\"\"Import a PyO3 extension, compiling it locally when permitted and needed.\n\n    The crate is discovered from the workspace under ``rust/``: the one whose\n    Cargo manifest declares ``[package.metadata.sglang] python-module`` equal\n    to ``python_module`` (the same metadata setup.py uses for wheel builds), so\n    new crates need no registration here.\n\n    ``auto`` prefers a module bundled in the installed wheel, then a cached\n    local build, and finally Cargo. ``never`` permits the first two but never\n    invokes Cargo. ``force`` rebuilds from source and replaces the cache entry.\n    ``mode`` defaults to ``SGLANG_RUST_BUILD_MODE``.\n    \"\"\"\n    if mode is None:\n        mode = envs.SGLANG_RUST_BUILD_MODE.get()\n    if mode not in (\"auto\", \"never\", \"force\"):\n        raise ValueError(\n            f\"invalid Rust extension build mode {mode!r}; expected auto, never, or force\"\n        )\n\n    if mode != \"force\":\n        module = _import_bundled_extension(python_module)\n        if module is not None:\n            return module\n    elif python_module in sys.modules:\n        raise RuntimeError(\n            f\"cannot force-build {python_module} after it has been imported; \"\n            \"start a new Python process\"\n        )\n\n    if workspace is None:\n        workspace = _RUST_WORKSPACE\n    crate = _discover_crate(workspace, python_module)\n    context = _build_context(crate)\n    cache_root = _cache_root(cache_dir)","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/rust_extensions/loader.py#L70-L106","documentation":"load_rust_extension(mode=...) only accepts 'auto', 'never', or 'force'. Any other mode string raises this ValueError; when mode is None the value comes from the SGLANG_RUST_BUILD_MODE env var. 'auto' uses bundled or cached builds, 'never' forbids invoking Cargo, 'force' rebuilds from source and replaces the cache entry.","triggerScenarios":"Passing mode=\"always\", \"True\", or \"\" to load_rust_extension; setting SGLANG_RUST_BUILD_MODE to anything other than auto/never/force and calling the loader without an explicit mode.","commonSituations":"Copy-pasting build-mode values from other tools (e.g. 'always' instead of 'force'); typos in CI env vars; docs or examples referencing a removed mode name.","solutions":["Set mode (or SGLANG_RUST_BUILD_MODE) to exactly auto, never, or force","If you wanted rebuild-on-every-call semantics, that is 'force'","Unset the env var to fall back to the default behavior instead of an invalid literal"],"exampleFix":"# before\nSGLANG_RUST_BUILD_MODE=always python -m ...\n# after\nSGLANG_RUST_BUILD_MODE=force python -m ...","handlingStrategy":"validation","validationCode":"assert mode in {\"auto\", \"never\", \"force\"}, f\"bad build mode {mode!r}\"","typeGuard":"def is_valid_build_mode(mode: str) -> bool:\n    return mode in {\"auto\", \"never\", \"force\"}","tryCatchPattern":null,"preventionTips":["Use an enum or constant set for build-mode values instead of free-form strings","Validate SGLANG_RUST_BUILD_MODE at app startup, not at first extension load"],"tags":["rust-extension","build-mode","env-var","validation","sglang"],"backgroundTag":"invalid-build-mode","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}