fix: guarded empty-path route skips cleanly; honor intoPath alias#600
Merged
Conversation
A guarded simple route with an empty path crashed with "the option `_file'
does not exist" when the guard was false: the raw collector module
(`{ key; _file; imports }`) was merged under `config` — mis-reading module
metadata as option definitions — and gated with `mkIf`, which still requires
the target option to exist even when the condition is false.
`guardModule` now mirrors the forward path: it gates with `lib.optionalAttrs`
(dropping the subtree entirely when false) and recurses into structural
imports, leaving module metadata at module level.
Separately, `policy.route` silently dropped the `intoPath` key (only `path`
was read), landing content at the class root instead of nesting. `route` now
accepts `intoPath` as the public alias for `path` — pairing with `intoClass`
and `fromClass` to match the forward API — and throws if both are given.
Regression tests in deadbugs cover both: guard-false skips cleanly, and
`intoPath` nests at the target path.
fmway
approved these changes
Jun 9, 2026
fmway
left a comment
Collaborator
There was a problem hiding this comment.
Bug 2 — policy.route silently drops intoPath
I was wondering why the error in the repro is different from the one in my configuration, then I realized it's because I write intoPath instead of path 😅
Just tested in my configuration, and it works well. I think this can be merged.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes two related bugs in simple
policy.route, surfaced by a guarded route usingintoPath.Bug 1 — guarded empty-path route crashes when the guard is false
A guarded route whose source is the raw collector module (
{ key; _file; imports }, the empty-path case) crashed with:Two causes in
nix/lib/aspects/fx/route/wrap.nixguardModule:config, so module metadata (_file/key/imports) was mis-read as option definitions.lib.mkIf— butmkIf falsestill requires the target option to exist, so an empty-path route into an undeclared option fails type-checking even when skipped.The forward path (
forward.nixguardFn) already handles this correctly withlib.optionalAttrs.guardModulenow mirrors it: gates withoptionalAttrs(dropping the subtree entirely when false) and recurses into structural imports, leaving module metadata at module level.Bug 2 —
policy.routesilently dropsintoPathrouteonly readroute.path; anintoPathkey (the name the forward API uses, pairing withintoClass/fromClass) was silently dropped, landing content at the class root instead of nesting. Confirmed:intoPath = [ "wrapper" ]placed content at the nixos root →error: The option 'items' does not exist.routenow acceptsintoPathas the public alias forpath(normalizing to the internalpath), and throwsden: policy.route: pass either 'intoPath' or 'path', not bothif both are given.pathstill works.Tests
New regression suite
templates/ci/modules/deadbugs/route-intopath-conditional-leak.nix:test-guarded-route-skips-cleanly— guard false → route contributes nothing, no crash.test-intopath-nests—intoPathnests content at the target path.Full CI: 866/866 passing. Formatted with
just fmt.