fix: render trigger action parameters as plain strings (closes #9742)#9747
Conversation
There was a problem hiding this comment.
No issues found across 1 file
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
Shadow auto-approve: would auto-approve. Adds a failing unit test reproducing a Jinja template rendering bug in webhook automation. No source code changes, minimal risk.
Re-trigger cubic
This comment was marked as outdated.
This comment was marked as outdated.
There was a problem hiding this comment.
0 issues found across 2 files (changes from recent commits).
Shadow auto-approve: would auto-approve. Fixes webhook parameter rendering for non-JSON-native types by wrapping scalars as explicit jinja kind dicts. Changes are isolated to webhook trigger builder, well-tested, and no broader system impact.
Re-trigger cubic
This comment was marked as outdated.
This comment was marked as outdated.
Provide a single helper that marks a single-expression Jinja action parameter as an explicit jinja kind, so Prefect renders it as a plain string instead of JSON-serializing the rendered value. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Emit the webhook trigger's scalar action parameters via the jinja_parameter helper so a firing automation renders the event id, occurred time, and an absent branch resource as strings, dispatching the webhook-process deployment for every triggering event including events with no associated branch. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Apply the jinja_parameter helper to the remaining trigger builders so their single-expression action parameters render as plain strings, hardening them against the same serialization failure when an event lacks a referenced resource key. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
b0b71a5 to
b317fcf
Compare
This comment was marked as outdated.
This comment was marked as outdated.
b317fcf to
aaf911b
Compare
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
aaf911b to
4d837c2
Compare
|
AGENT_REVIEW_VERDICT: FIX_APPROVED Overall verdict: APPROVEDThis re-review confirms the fix is complete and both non-blocking items from A. Correctness — solid
B. Code quality — good
C. Documentation alignment — now resolved
D. Test quality — good
Suggestions (non-blocking)
Recommended next steps
AGENT_REVIEW_ITERATION: fix-3
|
Add a knowledge-doc section describing how trigger action parameters are rendered server-side by Prefect and why single-expression values must be emitted via the jinja_parameter helper, and correct a stale builder reference in the webhook doc. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
There was a problem hiding this comment.
0 issues found across 2 files (changes from recent commits).
Shadow auto-approve: would auto-approve. Adds a jinja_parameter helper and applies it to all event-driven action parameters to prevent Prefect serialization failures. Mechanical changes across multiple trigger builders with tests.
Re-trigger cubic
| event="infrahub.node.created", | ||
| payload={"data": {"node_id": "abc"}, "context": {}}, | ||
| resource=Resource({"prefect.resource.id": "infrahub.account.xyz"}), | ||
| ) |
There was a problem hiding this comment.
I don't see a datetime in here, which is what the comment describes, but perhaps it happens behind-the-scenes
There was a problem hiding this comment.
It's defaulted to today's date, but you're right, explicit is better than implicit. And a fixed date is better than a moving one from a test perspective
| rendered = hydrate( | ||
| parameters, | ||
| HydrationContext(raise_on_error=True, render_jinja=True, jinja_context={"event": event}), | ||
| ) |
There was a problem hiding this comment.
this looks like we are testing Prefect's code, which we don't really have control over. if this test covers something that the functional test does not, then it might be worth keeping. otherwise it seems like it will be too brittle to be valuable
There was a problem hiding this comment.
Good point. This is what was executed behind the scenes during parameters serialization. Since we have the component test covering this, I think we can remove it. Useful at the review step but not further.
Pass the event's occurred time explicitly so the datetime value the comment describes is visible in the test rather than relying on the model default. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
The unit test replayed Prefect's private parameter-render path to assert template output. The emit-contract is covered structurally by the component test and the end-to-end behavior by the live functional test, so remove the test that coupled to Prefect internals. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
There was a problem hiding this comment.
0 issues found across 2 files (changes from recent commits).
Shadow auto-approve: would auto-approve. Bug fix: wraps Jinja template parameters to prevent Prefect serialization failure. Systematic, low-risk change across trigger definitions and tests.
Re-trigger cubic
This comment was marked as off-topic.
This comment was marked as off-topic.
…#9747) * feat(trigger): add jinja_parameter helper for action parameters Provide a single helper that marks a single-expression Jinja action parameter as an explicit jinja kind, so Prefect renders it as a plain string instead of JSON-serializing the rendered value. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * fix(webhook): render action parameters as plain strings (#9742) Emit the webhook trigger's scalar action parameters via the jinja_parameter helper so a firing automation renders the event id, occurred time, and an absent branch resource as strings, dispatching the webhook-process deployment for every triggering event including events with no associated branch. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * refactor: render trigger action parameters as plain strings Apply the jinja_parameter helper to the remaining trigger builders so their single-expression action parameters render as plain strings, hardening them against the same serialization failure when an event lacks a referenced resource key. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * chore: add changelog fragments for #9742 Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * docs: document trigger action-parameter rendering contract Add a knowledge-doc section describing how trigger action parameters are rendered server-side by Prefect and why single-expression values must be emitted via the jinja_parameter helper, and correct a stale builder reference in the webhook doc. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * test: set an explicit occurred datetime on the webhook render event Pass the event's occurred time explicitly so the datetime value the comment describes is visible in the test rather than relying on the model default. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * test: drop brittle render test that exercised Prefect internals The unit test replayed Prefect's private parameter-render path to assert template output. The emit-contract is covered structurally by the component test and the end-to-end behavior by the live functional test, so remove the test that coupled to Prefect internals. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> --------- Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
Why
Webhook automations crashed at Prefect parameter-render time, so no HTTP request was ever sent. Trigger definitions emitted single-expression action parameters as bare Jinja strings;
RunDeployment._upgrade_v1_templatesappends| tojsonto them, andjson.dumps()fails on values that are not JSON-native (aUUID, adatetime) or that resolve to an absent resource key (ChainableUndefined).The
| tojsoncoercion was introduced in Prefect 3.6.24 (PrefectHQ/prefect#21231); it is absent in 3.6.23 and earlier. The crash surfaced once we moved toprefect==3.7.5(Infrahub 1.10.0, up from3.6.13). Webhooks were the visible victim because custom webhooks default toevent_type="all", so they receive branch-less events (e.g. account events) where the branch key is missing. The same bare-string pattern existed in seven other trigger builders; they did not crash only because their narrow event triggers always carry the referenced keys.Closes #9742
What changed
jinja_parameter()helper that wraps a template as an explicit{"__prefect_kind": "jinja", "template": ...}parameter — Prefect's documented way to mark a templated parameter, which Prefect leaves untouched by thetojsonupgrade. Apply it to every single-expression action parameter across all trigger builders.How to review
Start with
backend/infrahub/trigger/models.py(jinja_parameterhelper), thenbackend/infrahub/webhook/models.py(the fix). The remaining builder edits are mechanical applications of the same helper. Commits are atomic: helper → webhook fix+tests → systemic hardening → changelog.How to test
Manual end-to-end verification (full Docker stack)
Verified on a live
dev.startstack (real server, Prefect, two task-workers) with a custom webhook (event_type=all) pointing at a local capture server:infrahub.node.created): webhook delivered; payload carried the previously-crashing values as strings —"id"(UUID) and"occured_at"(datetime).infrahub.account.logged_in, whose resource has noinfrahub.branch.name): webhook also delivered — theChainableUndefinedpath.TypeError: Object of type UUID is not JSON serializable→Action failed: 'Unable to create flow run from deployment: InvalidJinja()', exactly the reported failure.Checklist