{"record":{"id":"084a5054259da3ce","repo":"sgl-project/sglang","slug":"env-field-name-template-r-must-contain-glob","errorCode":null,"errorMessage":"{env_field.name}={template!r} must contain '{{global_rank}}': each rank needs its own path, and a rank-independent one would point every rank at a single daemon.","messagePattern":"(.+?)=(.+?) must contain '(.+?)\\}': each rank needs its own path, and a rank-independent one would point every rank at a single daemon\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/weight_cache/protocol.py","lineNumber":315,"sourceCode":"    \"\"\"\n    return (\n        base_gpu_id\n        + (pp_rank % pp_size_per_node) * tp_size_per_node\n        + (tp_rank % tp_size_per_node) * gpu_id_step\n    )\n\n\ndef _format_daemon_path(env_field, global_rank: int) -> str:\n    \"\"\"Fill in a daemon path template, rejecting one that drops the rank.\n\n    The template is user-overridable, and ``str.format`` silently ignores a\n    missing placeholder. Every rank would then derive the same path and map the\n    shard belonging to whichever daemon got there first, so refuse up front\n    rather than serve wrong weights.\n    \"\"\"\n    template = env_field.get()\n    if \"{global_rank}\" not in template:\n        raise ValueError(\n            f\"{env_field.name}={template!r} must contain '{{global_rank}}': each \"\n            f\"rank needs its own path, and a rank-independent one would point \"\n            f\"every rank at a single daemon.\"\n        )\n    return template.format(global_rank=global_rank)\n\n\ndef get_socket_path(global_rank: int) -> str:\n    \"\"\"Get the Unix socket path for a weight cache daemon.\n\n    global_rank = tp_size * pp_rank + tp_rank\n    \"\"\"\n    return _format_daemon_path(envs.SGLANG_WEIGHT_CACHE_SOCKET_TEMPLATE, global_rank)\n\n\ndef get_ready_path(global_rank: int) -> str:\n    \"\"\"Get the ready-file path for a weight cache daemon.\n","sourceCodeStart":297,"sourceCodeEnd":333,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/weight_cache/protocol.py#L297-L333","documentation":"_format_daemon_path requires the socket/ready path template (env var) to contain '{global_rank}'. A rank-independent path would point all TP ranks at one daemon and they would map the wrong shard, so it refuses up front.","triggerScenarios":"Setting SGLANG_WEIGHT_CACHE_*_PATH (socket or ready template) without the {global_rank} placeholder; called from get_socket_path/get_ready_path.","commonSituations":"User overrides the default per-rank path template with a fixed path like /tmp/wcache.sock when running tensor parallel > 1.","solutions":["Add {global_rank} to the template, e.g. /tmp/wcache-rank{global_rank}.sock","Use the default template by unsetting the env var"],"exampleFix":"# before\nexport SGLANG_WEIGHT_CACHE_SOCKET_PATH=/tmp/wcache.sock\n# after\nexport SGLANG_WEIGHT_CACHE_SOCKET_PATH=/tmp/wcache-rank{global_rank}.sock","handlingStrategy":"validation","validationCode":"if '{global_rank}' not in template:\n    raise ValueError('add {global_rank} to path template')","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always include {global_rank} in per-rank path templates","Prefer default paths"],"tags":["config","env-var","weight-cache","tensor-parallel"],"backgroundTag":"invalid-path-template","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}