Skip to content

fix: show FEEL expression for unresolvable function invocations#104

Open
barinali wants to merge 1 commit intomainfrom
issue-5744-show-expression-for-unresolvable-values
Open

fix: show FEEL expression for unresolvable function invocations#104
barinali wants to merge 1 commit intomainfrom
issue-5744-show-expression-for-unresolvable-values

Conversation

@barinali
Copy link
Copy Markdown
Member

@barinali barinali commented Apr 18, 2026

Related to camunda/camunda-modeler#5744

Proposed Changes

This pull request aims to preserve the FEEL expression for the built-in functions for downstream to display them on the user-interface. This pull request is enabled by lezer-feel changes.

Before

image
**After** image

Tests

The tests can be observed in #105 with the necessary changes from the lezer-feel pull request.

Steps to try out

This is the command I'd have suggested to experiment with variable over variable-outline, but I had no luck having it run so far. I think it's failing because linked dependencies are not direct dependencies of variable-outline and they're not declared as overrides by @bpmn-io/sr.

npx @bpmn-io/sr bpmn-io/variable-outline -l bpmn-io/variable-resolver#issue-5744-show-expression-for-unresolvable-values -l bpmn-io/lezer-feel#issue-5744-fix-function-invocation-value

Checklist

Ensure you provide everything we need to review your contribution:

  • Contribution meets our definition of done
  • Pull request establishes context
    • Link to related issue(s), i.e. Closes {LINK_TO_ISSUE} or Related to {LINK_TO_ISSUE}
    • Brief textual description of the changes
    • Screenshots or short videos showing UI/UX changes
    • Steps to try out, i.e. using the @bpmn-io/sr tool

@barinali barinali self-assigned this Apr 18, 2026
@barinali barinali requested review from a team and Copilot April 18, 2026 00:14
@barinali barinali added the bug Something isn't working label Apr 18, 2026
@bpmn-io-tasks bpmn-io-tasks bot added the needs review Review pending label Apr 18, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adjusts Zeebe FEEL expression resolution to preserve the original FEEL expression when function invocations cannot be resolved at design time, enabling downstream UI to display the expression instead of an empty value.

Changes:

  • Preserve FEEL expression as info for unresolved (type Any) function invocation results.
  • Normalize certain unresolved leaf entries in computed context results for display purposes.
  • Add regression tests + a BPMN fixture covering function invocation cases; update changelog.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
test/spec/zeebe/ZeebeVariableResolver.spec.js Adds tests ensuring unresolved function calls expose the FEEL expression and nested context results are retained.
test/fixtures/zeebe/function-invocation.bpmn New BPMN fixture with output mappings using FEEL built-in function invocations and a context-defined function.
lib/zeebe/util/feelUtility.js Updates FEEL resolution to preserve expressions for unresolved results; adjusts unified-format conversion for unresolved leaf entries.
CHANGELOG.md Documents the fix in the Unreleased section.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +670 to +675
// Entries with unknown type, no info, and no sub-entries are values
// that cannot be determined at design time (e.g. nested results of
// unresolvable function invocations). In FEEL, absent values are null,
// there is no "unknown" concept. So we normalize these to Null.
if (annotated.type === 'Any' && !annotated.info &&
(!entries || !entries.length)) {
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new AnyNull normalization will rewrite any leaf entry with unknown type + no info into { type: 'Null', info: 'null' }. That can misrepresent legitimate “unknown at design time” values (e.g. context outputs that forward runtime-provided variables) as proven-null. Consider narrowing this condition (e.g. only normalize when atomicValue === null, or add a guard to avoid rewriting values that originate from scoped variables).

Suggested change
// Entries with unknown type, no info, and no sub-entries are values
// that cannot be determined at design time (e.g. nested results of
// unresolvable function invocations). In FEEL, absent values are null,
// there is no "unknown" concept. So we normalize these to Null.
if (annotated.type === 'Any' && !annotated.info &&
(!entries || !entries.length)) {
// Only normalize unknown leaf values to FEEL null when the source value
// explicitly represents null. Other leaf `Any` values may simply be
// unknown at design time (for example, forwarded scoped/runtime values)
// and must not be rewritten as proven-null.
if (annotated.type === 'Any' && !annotated.info &&
(!entries || !entries.length) &&
has(variable, 'atomicValue') && variable.atomicValue === null) {

Copilot uses AI. Check for mistakes.
Comment thread lib/zeebe/util/feelUtility.js Outdated
@barinali barinali force-pushed the issue-5744-show-expression-for-unresolvable-values branch from 3095f41 to a867dcc Compare April 18, 2026 00:30
@barinali barinali requested review from Buckwich and nikku April 18, 2026 00:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working needs review Review pending

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants