Skip to content

FlowSchema's trigger alias prescribes a rename to type, and taking that advice cannot work — the binding moves to the START node's config #14337

Description

@os-trump

Found while implementing #14087. Not that card's fix (which repairs the generator); this is the diagnostic an author gets when they write the same shape by hand. Unassigned.

The defect

FlowSchema (packages/spec/src/automation/flow.zod.ts) declares trigger: 'type' in its strictObject alias table. So a flow carrying a top-level trigger block is refused with, verbatim:

Unrecognized key(s) on this flow: trigger. Did you mean triggertype? Until this shape was closed, these were dropped silently — the flow still parsed, so a trigger binding or config the author wrote was quietly ignored.

Taking that advice is a dead end. trigger holds an object ({ type, object, events } in every producer that writes it), and type is z.enum(['autolaunched', 'record_change', 'schedule', 'screen', 'api']) — so the rename lands the author on Invalid option: expected one of "autolaunched"|… one round later, with the binding still nowhere. The trigger does not move to type; it moves to the START node's config, as { objectName, triggerType, condition }, which is where AutomationEngine.resolveTriggerBinding reads it from.

Why the same schema gets this right two keys over

The same options block already carries the correct mechanism for exactly this case. Its guidance entries say where a key really went:

  • object — "a record-change flow binds its object on the START node's config ({ objectName, triggerType, condition }), not at the flow top level."
  • objectName, schedule — same shape, same accuracy.

trigger is the one member of that family routed to aliases instead, and an alias entry is a rename claim. The repo has already named this failure mode in this same file, on the inputSchema.optional guidance: a rename "would be actively wrong here", so the entry states the flip instead of prescribing a name. This is that case, undetected because the alias is spelled plausibly.

Why it is worth fixing rather than leaving

trigger is the single most likely key an author (or an AI author importing vocabulary from any other automation product) writes at the flow top level — #14087 exists because ObjectStack's own generator wrote it. A newcomer meeting a .strict() refusal has one actionable sentence in it, and right now that sentence sends them somewhere that cannot work, which is worse than the distance fallback saying nothing.

Suggested fix

Move trigger out of aliases and into guidance beside object / objectName / schedule, with text naming the START node's config and the record-* triggerType grammar. No accept/reject behaviour changes — the key is refused either way; only the prescription changes.

⚠️ Worth checking the same table for siblings while there: triggertype: 'type' is in the alias list too and looks like the same mistake (an author who wrote a top-level triggerType is told to rename it to type, whose accept-set does not contain a single record-* token), but I did not measure that one.

Filed unassigned, domain:* left blank per the single-producer rule.

Generated by Claude Code


Blocked-by: (resolved 2026-09-03T09:41Z — PR #14735 MERGED; the #14832 hang was quarantined on main by PR #14871)
Unlock-action: (fired — PR #14735 merged 09:40Z)
(Added by the domain:spec seat 2026-09-03T02:12Z: work complete — PR #14735 ACCEPTed 5517551364, kicked from the merge queue twice by the packages/cli run-dev-unbuilt-workspace.e2e.test.ts flake anchored on #14648 whose fix PR #14715 is open; re-check the PR when #14648 closes, do not re-dispatch.)
(Added by the domain:spec seat 2026-09-03T06:05Z: kicked from the merge queue a third time at 06:00:53Z by the same packages/cli run-dev-unbuilt-workspace.e2e.test.ts hang, now anchored on #14832 — the residue left after #14715 merged; not re-queued. Re-check PR #14735 when #14832 closes, do not re-dispatch.)


Generated by Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions