{"record":{"id":"b0a74a8273691cf6","repo":"zeroclaw-labs/zeroclaw","slug":"gateway-web-dist-dir-path-reason-gate","errorCode":null,"errorMessage":"gateway.web_dist_dir = \"{$path}\" — {$reason}; gateway.web_dist_dir is read verbatim, so expand the value yourself (e.g. an absolute path)","messagePattern":"gateway\\.web_dist_dir = \"(.+?)\" — (.+?); gateway\\.web_dist_dir is read verbatim, so expand the value yourself \\(e\\.g\\. an absolute path\\)","errorType":"console","errorClass":"DiagItem","httpStatus":null,"severity":"warning","filePath":"crates/zeroclaw-runtime/src/doctor/mod.rs","lineNumber":1400,"sourceCode":"            cat,\n            format!(\"{} (at {})\", warning.message, warning.path),\n        ));\n    }\n}\n\nfn check_web_dist_dir(config: &Config, items: &mut Vec<DiagItem>) {\n    let cat = \"config\";\n    match config.gateway.web_dist_dir.as_deref() {\n        None => {}\n        Some(value) => match web_dist_dir_expansion_reason_key(value) {\n            None => {}\n            Some(reason_key) => {\n                let reason = crate::i18n::get_required_cli_string(reason_key);\n                let message = crate::i18n::get_required_cli_string_with_args(\n                    \"cli-doctor-web-dist-dir-expansion-warning\",\n                    &[(\"path\", value), (\"reason\", reason.as_str())],\n                );\n                items.push(DiagItem::warn(cat, message));\n            }\n        },\n    }\n}\n\n/// Return the Fluent reason key when `value` looks like it expects\n/// shell expansion the gateway will not perform. `None` means the value\n/// is a literal path that the gateway can resolve as-is.\nfn web_dist_dir_expansion_reason_key(value: &str) -> Option<&'static str> {\n    if value.starts_with('~') {\n        Some(\"cli-web-dist-dir-reason-tilde\")\n    } else if value.contains('$') {\n        Some(\"cli-web-dist-dir-reason-dollar\")\n    } else {\n        None\n    }\n}\n","sourceCodeStart":1382,"sourceCodeEnd":1418,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-runtime/src/doctor/mod.rs#L1382-L1418","documentation":"A `zeroclaw doctor` warning from `check_web_dist_dir`: `gateway.web_dist_dir` starts with `~` or contains `$`, i.e. it looks like it expects shell expansion. The gateway reads the value verbatim and performs no expansion, so the dashboard static files would be served from a literally-named (nonexistent) directory. The localized message is built from the Fluent keys `cli-doctor-web-dist-dir-expansion-warning` plus a reason key (`cli-web-dist-dir-reason-tilde` or `cli-web-dist-dir-reason-dollar`).","triggerScenarios":"Running `zeroclaw doctor` when `gateway.web_dist_dir` is set to a tilde path (`~/zeroclaw/web/dist`) or contains a dollar sign (`$HOME/zeroclaw/web/dist`, `${INSTALL_DIR}/web/dist`). Detection is `value.starts_with('~')` or `value.contains('$')`.","commonSituations":"Porting a shell-style path from documentation or dotfiles into zeroclaw.toml; CI templates that substitute variables at write time but leave the `$` syntax when substitution is disabled.","solutions":["Replace the value with a literal absolute path, e.g. `/home/user/zeroclaw/web/dist`.","Expand the variable yourself before writing config: `zeroclaw.toml` written by a script should already contain the expanded result of `$HOME`.","If the dashboard is not needed, remove `gateway.web_dist_dir` instead of leaving a broken path.","Re-run `zeroclaw doctor` to confirm the warning is gone."],"exampleFix":"# before\n[gateway]\nweb_dist_dir = \"~/zeroclaw/web/dist\"\n\n# after\n[gateway]\nweb_dist_dir = \"/home/user/zeroclaw/web/dist\"","handlingStrategy":"validation","validationCode":"if let Some(dir) = config.gateway.web_dist_dir.as_deref() {\n    assert!(\n        !dir.starts_with('~') && !dir.contains('$'),\n        \"gateway.web_dist_dir is read verbatim — expand it to a literal absolute path\"\n    );\n}","typeGuard":"fn web_dist_dir_is_literal(path: &str) -> bool {\n    !path.starts_with('~') && !path.contains('$')\n}","tryCatchPattern":null,"preventionTips":["Expand paths at config-generation time; never rely on the gateway to expand them.","Prefer absolute paths for anything under [gateway]."],"tags":["config","gateway","paths","doctor","zeroclaw"],"backgroundTag":"tilde-path-not-expanded","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}