Skip to content

v0.9.0 — a YAML tool that contradicts itself no longer loads

Choose a tag to compare

@callobuzz callobuzz released this 31 Aug 17:54
· 3 commits to main since this release

Breaking. A YAML tool whose declaration contradicts its own query no longer loads. A server carrying one will refuse to start instead of running it wrongly, and the message names the tool, the file and the field.

The line this release deletes

convertInputType ended in default: z.string(), so any type: the loader did not implement quietly became a string.

  • type: integer loaded fine, then rejected 5 and accepted "5" — sending Shopify text where the schema wanted a number, with the error blaming the caller's argument rather than the declaration.
  • It is the same line that made array look supported before 0.8.0 implemented it: type: array loaded, then failed at call time with Expected string, received array.

The vocabulary is now exactly string, number, boolean, enum, array, object. A missing type: is refused too, and a nested field is named by path:

YAML tool "my_tool" at "./my-tools/thing.yaml": input "lines.items.quantity" has unknown
type "integer". Valid types: string, number, boolean, enum, array, object

input: and your GraphQL variables must be the same set

A YAML tool has no handler — the engine runs shopify.query(tool.graphql, validatedInput) and nothing else — so the declared input is the variable set. Either half of a mismatch is silent at runtime:

  • a variable no input: declares can never be supplied, and GraphQL reads an absent optional variable as "not specified";
  • an input: no variable uses is validated and then dropped, so the tool advertises a parameter it ignores.

One typo produces both, which is how it gets caught. A $ inside a string literal, a # comment or a """ block is not counted, so query: "price:>$100" still loads.

What that check found on its first run

complete_draft_order, shipped in custom-tools/ since it was added, declared payment_pending while its mutation used $paymentPending. The caller's value was validated, sent under a name the mutation did not reference, and $paymentPending arrived null — which Shopify reads as false.

Asking for a pending payment completed the draft order as paid. No error, anywhere. The mutation now uses $payment_pending; the tool's input schema is unchanged, so callers need no edit.

Upgrading

If a tool stops loading, the message names the exact field. There are only two shapes: a type: that is not in the list, and an input:/$variable set that does not match.

Every YAML tool reachable from the release machine — the 2 shipped here and 12 in the reference consumer — was loaded through the new loader before release. One failed: complete_draft_order, above.

Full changelog: https://github.com/callobuzz/cob-shopify-mcp/blob/main/CHANGELOG.md