fix(passkey-email): mark unrendered Browser/Device variables optional - #86
Merged
Merged
Conversation
milo's EmailTemplate admission webhook rejects any template whose required variable is not referenced in both htmlBody and textBody. The passkey template declares Browser and Device (producers still send them) but no longer renders them, so staging's Flux apply of the fixed bundle has been failing since Jul 29 and staging stayed pinned to the Jul 24 bundle that still shows the empty rows. generate-yaml.js now derives each variable's required flag from whether the rendered html/text output actually references it, so the bundle stays acceptable to milo by construction. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NWH7RtwJ1b4Dz3WyJXQTCD
mattdjenkinson
approved these changes
Jul 30, 2026
felixwidjaja
approved these changes
Jul 30, 2026
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
The PR #82 fix (dropping the empty Browser/Device rows) merged and published fine, but staging never applied it: the Flux Kustomization
datum-email-templates-customizationhas been inReconciliationFailedsince Jul 29, pinned to the Jul 24 bundle (v0.0.0-main-20260724-023346) — which is why staging emails still show the empty rows.Root cause: milo's EmailTemplate admission webhook requires every
required: truevariable to be referenced in bothhtmlBodyandtextBody(pkg/email/templating/{html,text}validator.go). PR #82 removed the{{.Browser}}/{{.Device}}references, butscripts/generate-yaml.jshardcodesrequired: truefor every PreviewProps key — so milo rejects the new template and Flux retries forever on the old bundle. Invisible in CI, since the webhook only runs at apply time in-cluster.Fix: the generator now derives each variable's
requiredflag from whether the rendered html/text output actually references it. Declared-but-unrendered variables (kept declared because producers still send them, and undeclared sent variables are rejected at send time) are emitted asrequired: false, which milo accepts. This makes the "webhook rejects bundle, Flux silently stuck" failure class impossible by construction.Bundle diff is exactly the fix: only
Browser/Deviceflip torequired: falseinuserpasskeyadded-emailtemplate.yaml; all other templates are byte-identical.Test plan
pnpm generate:allwith lockfile-pinned deps — only the passkey YAML variables changedatum-email-templates-customizationbecomesReadyand its revision advances to the newv0.0.0-main-*tag (OCIRepository polls every 5m, failing Kustomization retries every 2m)Related
node_modules(react-email 6.5.0 vs lockfile's 6.9.0), not a real change