Skip to content

feat(workflow): Mustache lambda helpers for missing-key defaults (fn.*)#5684

Merged
shahargl merged 2 commits intokeephq:mainfrom
hakatt:feature/workflow-fn-helpers
Mar 11, 2026
Merged

feat(workflow): Mustache lambda helpers for missing-key defaults (fn.*)#5684
shahargl merged 2 commits intokeephq:mainfrom
hakatt:feature/workflow-fn-helpers

Conversation

@hakatt
Copy link
Copy Markdown
Contributor

@hakatt hakatt commented Feb 25, 2026

Summary

Closes #5682. Also addresses the root cause of #5070 and is a lighter-weight alternative to the Jinja migration requested in #4594.

Injects a set of named lambda helpers into every Chevron render context so workflow templates can safely reference custom or enriched alert fields that may be absent — without triggering RenderException:

# Empty or missing → "N/A"
body: "Panel: {{#fn.na}}{{ alert.panelUrl }}{{/fn.na}}"

# Empty or missing → ""
if: "{{#fn.default}}{{ alert.slack_timestamp }}{{/fn.default}}"

# Transform
body: "Severity: {{#fn.upper}}{{ alert.severity }}{{/fn.upper}}"

Changes

Backend keep/iohandler/iohandler.py (+23 lines):

  • WORKFLOW_HELPERS constant with fn.{default,na,upper,lower,strip} Chevron lambdas
  • Merged into context on every _render() call
  • Safe mode auto-disabled when template contains {{#fn. (lambda already returns a safe default, so RenderException must not be raised)

Frontend keep-ui/entities/workflows/lib/mustache.ts (+3 lines):

  • Filter Mustache sigil tokens (#, /, ^, !, >) from extractMustacheVariables() so the workflow builder doesn't flag {{#fn.na}}/{{/fn.na}} as invalid variable references

Design rationale

See #5682 for the full two-category analysis. The short version:

  • Provider schema fields (e.g. panelUrl, instance) → defaulted in _format_alert(), no workflow-layer handling needed
  • Custom/enriched fields (e.g. slack_timestamp from enrich_alert, optional labels) → no provider can default these; fn.* helpers give workflow authors a clean per-field default syntax

This does not change behaviour for any existing workflow that does not use {{#fn. sections.

Test plan

  • Unit test: fn.na on missing key → "N/A"
  • Unit test: fn.default on missing key → ""
  • Unit test: fn.upper/fn.lower/fn.strip on present value
  • Frontend: open workflow builder with {{#fn.na}}{{ alert.x }}{{/fn.na}} — no "invalid variable" warning
  • End-to-end: all five helpers (fn.default, fn.na, fn.upper, fn.lower, fn.strip) validated on dev Keep 0.49.0-svt.10 — workflows run without RenderException

@vercel
Copy link
Copy Markdown

vercel bot commented Feb 25, 2026

@nflx is attempting to deploy a commit to the KeepHQ Team on Vercel.

A member of the Team first needs to authorize it.

@shahargl
Copy link
Copy Markdown
Member

shahargl commented Mar 2, 2026

@hakatt @nflx is this active?

@nflx
Copy link
Copy Markdown
Contributor

nflx commented Mar 3, 2026

@hakatt @nflx is this active?

Yes, we have it running well in our test environment and I will just finish writing the unit tests and rebase it. Thank you for the reminder @shahargl :-)

@hakatt hakatt force-pushed the feature/workflow-fn-helpers branch from 2854bbf to 862f50d Compare March 3, 2026 13:47
@hakatt hakatt marked this pull request as ready for review March 3, 2026 14:24
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 3, 2026

Target branch is not in the allowed branches list.

@dosubot dosubot bot added size:M This PR changes 30-99 lines, ignoring generated files. Feature A new feature labels Mar 3, 2026
@hakatt
Copy link
Copy Markdown
Contributor Author

hakatt commented Mar 5, 2026

PR ready, (if accepted).

hakatt added 2 commits March 11, 2026 13:33
…efaults

Inject a set of named lambda helpers into every Chevron render context so
workflow templates can safely reference custom or enriched alert fields that
may be absent without triggering RenderException:

  {{#fn.na}}{{ alert.someOptionalField }}{{/fn.na}}   → "N/A" if missing
  {{#fn.default}}{{ alert.slack_timestamp }}{{/fn.default}} → "" if missing
  {{#fn.upper}}{{ alert.severity }}{{/fn.upper}}       → uppercased value

Two-part change:

Backend (iohandler.py):
- Add WORKFLOW_HELPERS constant with fn.{default,na,upper,lower,strip} lambdas
- Inject into context on every _render() call
- Disable safe mode automatically when template contains {{#fn.}} sections
  (same pattern as existing {{^ inverted-section bypass); the lambda already
  returns a safe default so RenderException must not be raised

Frontend (mustache.ts, validate-mustache-yaml.ts, validate-mustache-ui-builder.ts):
- Filter Mustache sigil tokens (#, /, ^, !, >) from extractMustacheVariables()
  so the workflow builder does not flag {{#fn.na}} / {{/fn.na}} as invalid
  variable references
- Apply the same sigil guard inside validateMustacheVariableForYAMLStep() and
  validateMustacheVariableForUIBuilderStep() so the YAML editor's own inline
  extraction loop (which bypasses extractMustacheVariables) is also covered

This is Option E of the missing-key handling design; provider-level field
defaulting (Option A) remains correct for known provider schema fields.
Cover the three unchecked items from the PR test plan:
- fn.na on a missing alert field → 'N/A'
- fn.default on a missing alert field → ''
- fn.upper / fn.lower / fn.strip on a present field value
@hakatt hakatt force-pushed the feature/workflow-fn-helpers branch from 862f50d to 876197d Compare March 11, 2026 12:37
@shahargl shahargl merged commit d419029 into keephq:main Mar 11, 2026
14 of 16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feature A new feature size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Proposal] Workflow template engine: Mustache lambda helpers for missing-key defaults

3 participants