magus v0.3.0 is out. See what's new
¶ View markdown source · ✎ Suggest an edit
2 min read

MGS6001: charm patch does not apply to the command

magus describe target <name>:<charm> was asked to preview the charm-applied command, but applying the charm's JSON Patch to the target's argv failed. The patch is well-formed (it passed the shape check every charm declaration goes through) yet does not fit this target's actual arguments, so the charm would change nothing here.

[MGS6001] target "lint" in project ".": charm(s) [rw] do not apply to spell "go"'s
command (json-patch: index 7 out of range for argv of length 4)
  see: .../MGS6001.md

Why

A charm is an RFC 6902 patch over a target's argument vector (see charms). Magus validates a charm's shape when the spell loads: the op is one of the six, the path is a /-rooted JSON Pointer, a move/copy carries a from. That check cannot know whether the pointer resolves, because it does not have the target's argv in hand.

The pointer is only resolved when the charm is applied to a concrete command. Two well-formed patches fail at that point:

  • An out-of-range index. {"op": "add", "path": "/7", ...} against a four-element argv has nowhere to land. This is what a hand-written positional patch drifts into when the base command changes and the counted index is not updated (the reason the charm constructors anchor by value instead).
  • A failing test op. {"op": "test", "path": "/1", "value": "run"} asserts the element is still where the author expected; when it is not, the patch is rejected on purpose.

Before this diagnostic, magus describe silently dropped the command: line for such a target: the preview rendered without the charm and without a word, so you could not tell a charm had failed to apply until a real run. Magus now surfaces it, because a charm that is dead on a target is exactly the kind of deterministic-but-invisible gap describe exists to close.

Resolution

Fix the charm declaration so its patch fits the target's argv:

  • Prefer a value anchor over a counted index. Replace a literal "/7" with a constructor that resolves the position at author time (charm\after(args, "run", [...])), so the pointer tracks the argv instead of a stale count. See the constructor reference.
  • Check the base command. Run magus describe target <name> with no charm to see the argv the charm must patch, then confirm the index or anchor the charm targets actually exists in it.
  • Relax or remove a stale test op. A test op guards a position; if the base argv legitimately changed, update the asserted value or drop the guard.

What this is NOT

  • Not a malformed patch. A patch with a bad op name or a non-rooted path is rejected earlier, at spell load, not here. MGS6001 is specifically a well-formed patch that does not apply to this target.
  • Not a runtime failure. describe executes nothing. This is a static preview diagnostic; the same mismatch would also fail a real run, which is why surfacing it early is worthwhile.

See also

MGS6001charmsjson-patchrfc-6902describeargvpreview
Last updated (e0463131)
Earlier changes on this page (1)

Full history ↗ · Blame source ↗

Glossary

Project

A directory magus recognizes as a unit of work (it has a magusfile); the unit of caching, scheduling, and dependency tracking. See workspace.

Target

A named operation (build, test, ...) you invoke with magus run <target>; it may compose a spell's tool-native operations and depend on other targets. See targets.

Spell

A language/runtime adapter (e.g. go, md) that maps generic targets onto a toolchain's real commands. See spells.

Charm

An execution modifier attached with : (lint:rw) that changes how a target runs, not which one; the built-in rw flips a check-only target to mutate in place, and ci always strips it. See charms.

CI

An ordinary magusfile-defined target you compose yourself with magus\needs - magus does not hardcode its stages. Magus.RunCI treats it specially only in that it strips the rw charm, it is the anchor magus affected ci keys off, and a selected scope with no project declaring it is a load error rather than a silent no-op. See targets.

Conventions

Placeholders

Angle brackets mark a value you replace with your own - never type the brackets:

magus run <target>
magus completion <shell>    # e.g. bash, zsh, fish

<target>, <path>, <shell>, <name> and the like are stand-ins, not literal text.