Env-var expansion runs before TOML parsing, so ${VAR} in a comment breaks startup #31
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
routes_config::expand_env_refsscans the raw file text before the TOML is parsed, so it has no concept of a comment. Any${VAR}anywhere in the config demands thatER_VARbe set, or startup fails — including a placeholder inside a comment, or on a config line the operator has commented out.The practical consequences:
The shipped
edge-router.example.tomlcould not be loaded at all. Its TLS section documented the feature withUse ${VAR_NAME} to inject secrets…and a commented-out# cloudflare_api_token = "${CF_TOKEN}". Starting the router against the example we ship failed with:Commenting a line out can break a running deployment. Disable a service by commenting out its
cloudflare_api_tokenand the router stops starting, with an error pointing at a line that is no longer active config.Found by the
shipped_example_config_parsestest added in2f6e830— nothing had ever loaded that file, so it had drifted into being unloadable unnoticed.Current state
Worked around in
2f6e830by rewording the example's comments to describe the syntax in words instead of showing it, and documenting the trap inCLAUDE.md. That keeps the example loadable but makes those comments worse — their whole job was to show the${VAR}syntax, and they now can't.The test pins the example, so this can't silently regress.
Proposed fix
Expand after TOML parsing rather than before: parse to
toml::Value, walk the string leaves substituting placeholders, then deserialize intoRawRouteConfig. That is comment-safe and#-inside-a-string-safe by construction, rather than by a heuristic that tries to guess where comments start.Deliberately not done as a comment-stripping pass over the raw text:
password = "a#b"is a valid TOML value and any regex-ish approach either mangles it or needs to tokenize TOML properly anyway.Once fixed:
${VAR}examples inedge-router.example.toml's TLS section.CLAUDE.md'sroutes_config.rsrow.shipped_example_config_parses.Also worth checking while in there
The error message had doubled braces and rendered as a literal
'${{var_name}}', naming nothing useful. Fixed in2f6e830, with an assertion intest_expand_missing_var_returns_errorso it stays fixed — no action needed, just context if you're reading that code.