MGS1029: source glob reaches into a pruned directory
A target declares a source pattern whose directory prefix passes through a tree magus prunes, so it matches nothing and keys nothing.
[MGS1029] docs: source glob "proto/gen/*.binpb" can never match: the expansion
walk prunes "gen"
Why
The walk that builds a cache key skips four directory names wholesale, from
project.IgnoreDirs:
| directory | why it is pruned |
|---|---|
gen |
generated code: machine-written, never a discoverable project |
vendor |
Go vendored dependencies |
node_modules |
pnpm/npm dependencies |
target |
Rust build artifacts |
Pruning them is what keeps a broad pattern honest. A project declaring **/*.js
means its own sources; without the prune it would hash every file in
node_modules and key on a dependency tree nobody edits.
The cost is that a pattern aimed at one of those directories can never match. It is not an error at authoring time and not an error at run time - the glob is well-formed, it simply describes files the walk will not visit. The target then replays from cache while the files it named change underneath it.
This is the input-side twin of MGS1014, which catches a declared output that no run produces. Same shape: a declaration and reality quietly disconnected.
What it is not
An exact path is fine, and is not reported:
ctx.readsFiles(workspace.file("proto/gen/descriptor.binpb")); // works
ctx.readsFiles(workspace.file("proto/gen/*.binpb")); // MGS1029
A wildcard-free declaration names one file, so magus resolves it by stat rather than by the walk. It reaches the cache key normally even from inside a pruned tree. Only a pattern is unmatchable, because only a pattern could expand to swallow a dependency tree.
Fix
Name the file exactly, if you meant one file:
ctx.readsFiles(workspace.file("proto/gen/descriptor.binpb"));
Or declare the real sources instead of the generated artifact. A generated tree is downstream of something you own, and keying on that something is both narrower and more honest:
// not proto/gen/*.binpb - the schema the descriptor is built from
ctx.readsFiles(workspace.file("proto/magus/**/*.proto"));
If the files genuinely live under a pruned name and are genuinely sources,
rename the directory. gen, vendor, node_modules and target carry a
meaning across every magus workspace, and a hand-written source tree under one
of those names will surprise more than this check.
Confirming the fix
Ask what the cache key actually contains:
magus describe target <target> <project> --cache --inputs
Every hashed file appears as a src: line. If a file you declared is missing
from that list, it is not in the key, whatever describe target reports under
sources:.