Skip to content

fix: emit "empty" keyword for typed Java action arguments#521

Merged
ako merged 5 commits intomendixlabs:mainfrom
hjotha:submit/empty-java-action-list-arg
May 8, 2026
Merged

fix: emit "empty" keyword for typed Java action arguments#521
ako merged 5 commits intomendixlabs:mainfrom
hjotha:submit/empty-java-action-list-arg

Conversation

@hjotha
Copy link
Copy Markdown
Contributor

@hjotha hjotha commented May 5, 2026

Summary

When a Java action parameter is typed as a BasicParameterType (any inner type other than entity-type or microflow-type — String, Integer, Boolean, ListType, ParameterizedEntityType, DateTime, Decimal, …) and the MDL author binds it to empty, Studio Pro authors the BSON BasicCodeActionParameterValue with Argument: "empty" — the literal MDL keyword. The current builder collapses every empty primitive binding to Argument: "" (the unbound marker), regardless of parameter type. For typed parameters that substitution triggers mx check CE0126 "Missing value for parameter X" because the model treats the parameter as missing rather than explicitly empty.

Fix

When the Java action definition is resolvable via the backend, classify each parameter:

  • EntityTypeParameterType → already handled separately (EntityTypeCodeActionParameterValue).
  • MicroflowType → already handled separately (MicroflowParameterValue with empty Microflow).
  • Anything else (BasicParameterType — primitives, lists, parameterized-entity types) → emit Argument: "empty" for the MDL empty literal.

When jaDef == nil (no backend or action not resolvable) the builder keeps the prior Argument: "" behaviour to preserve the documented "intentionally unbound" semantics from PROPOSAL_microflow_empty_java_action_argument.md. The describer already maps both shapes to the MDL empty keyword so round-trip stays symmetric.

Reproduction

A Java action call that binds a typed parameter to empty:

call java action M.MyAction(items = empty);          -- ListType
call java action M.MyAction(key = empty);            -- StringType
call java action M.MyAction(microflowArgument = empty); -- ParameterizedEntityType

Before this PR: mx check reports CE0126 "Missing value for parameter X". After this PR: mx check reports 0 errors.

Test plan

  • Existing test TestBuildJavaAction_EmptyArgumentPreservesEmptyBasicValue continues to pass — without backend (jaDef == nil) primitives still emit Argument: "".
  • New parametrized test TestBuildJavaAction_EmptyResolvedBasicArgumentEmitsEmptyKeyword covers ListType and StringType — both must emit Argument: "empty" once the parameter type is resolved.
  • Existing test TestBuildJavaAction_EmptyMicroflowArgumentUsesMicroflowParameterValue continues to pass.
  • go test ./... passes.
  • Roundtrip audit on a 20-microflow random sample: previously failing DataLake.X (ParameterizedEntityType) and MxKafka.X (StringType) microflows now match, 18/18 unaffected microflows held their prior status — no regressions.

🤖 Generated with Claude Code

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 5, 2026

AI Code Review

Critical Issues

None found.

Moderate Issues

None found.

Minor Issues

None found.

What Looks Good

  • The fix correctly addresses the CE0126 error by distinguishing list-typed parameters when emitting the empty keyword in BSON.
  • The change is minimal and focused, adding only the necessary logic to track list-typed parameters and conditionally set the Argument field.
  • Test coverage is adequate: new test verifies the fix, existing tests continue to pass, and roundtrip audit confirms no regressions.
  • Comments clearly explain the rationale and the distinction between list-typed and primitive parameters.
  • The solution maintains symmetry with the describer (which already maps both shapes to MDL empty).
  • No changes to MDL syntax, grammar, or AST were needed since this is an execution-layer fix for existing syntax.

Recommendation

Approve the PR. The change is correct, well-tested, and maintains backward compatibility for primitive parameters while fixing the specific issue with list-typed Java action arguments.


Automated review via OpenRouter (Nemotron Super 120B) — workflow source

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 5, 2026

AI Code Review

What Looks Good

  • The PR correctly identifies and fixes a specific bug where list-typed Java action parameters bound to empty were incorrectly emitted as unbound markers
  • The solution is minimal and targeted, only affecting the specific case that was broken
  • Test coverage is adequate: adds a new test for the fix while ensuring existing tests still pass
  • The PR maintains round-trip symmetry as noted (the describer already handled both cases)
  • Code is well-commented explaining why the distinction between list-typed and primitive parameters matters
  • No unnecessary changes or scope creep - stays focused on the single issue
  • Follows existing code patterns and style in the file

Recommendation

Approve the PR. It addresses a concrete bug with a minimal, well-tested fix that doesn't modify MDL syntax or require full-stack pipeline changes. The change is strictly in the executor layer to correct BSON emission for a specific case, and all relevant checklist items are satisfied for this type of bug fix. No syntax design or full-stack consistency considerations apply since no MDL syntax is being added or modified.


Automated review via OpenRouter (Nemotron Super 120B) — workflow source

@hjotha hjotha changed the title fix: emit "empty" keyword for list-typed Java action arguments fix: emit "empty" keyword for typed Java action arguments May 5, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 5, 2026

AI Code Review

Critical Issues

None found.

Moderate Issues

None found.

Minor Issues

None found.

What Looks Good

  • The fix correctly addresses the core issue: distinguishing between "intentionally unbound" (empty string) and explicitly "empty" literal for typed Java action parameters when backend resolution is available.
  • The implementation cleanly separates parameter types into three categories (entity, microflow, basic) and handles the basic type case with the new resolvedBasicParams map.
  • Test coverage is comprehensive:
    • New parametrized test covers ListType and StringType (representing BasicParameterType) with backend resolution
    • Existing tests preserve behavior for unbound parameters (jaDef == nil) and microflow parameters
    • Roundtrip audit confirms no regressions in real-world microflows
  • Code changes are minimal and focused, with clear comments explaining the rationale and referencing the relevant proposal.
  • The fix maintains backward compatibility by preserving the original "" behavior when backend resolution fails.
  • No modifications to MDL syntax, grammar, AST, or visitor were needed (as this is purely an execution behavior fix), so full-stack consistency checks for new syntax don't apply.

Recommendation

Approve - The PR is ready for merging. It correctly resolves the reported issue with appropriate test coverage and maintains all existing behaviors. The change is minimal, well-documented, and follows the project's architectural patterns.


Automated review via OpenRouter (Nemotron Super 120B) — workflow source

@hjotha hjotha force-pushed the submit/empty-java-action-list-arg branch from f42c2b9 to 7b85f18 Compare May 5, 2026 14:46
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 5, 2026

AI Code Review

Critical Issues

None found.

Moderate Issues

None found.

Minor Issues

None found.

What Looks Good

  • The PR correctly addresses the reported issue where typed Java action parameters bound to empty were incorrectly emitting Argument: "" instead of Argument: "empty", causing mx check CE0126 errors.
  • The fix properly distinguishes between parameter types (EntityType, MicroflowType, and BasicParameterType) and only applies the "empty" keyword emission for resolved basic types.
  • The behavior preserves the existing unbound semantics (Argument: "") when the Java action definition is unavailable (jaDef == nil), maintaining compatibility with the documented intention in PROPOSAL_microflow_empty_java_action_argument.md.
  • Test coverage is comprehensive:
    • Existing test for unbound case preserved
    • New parametrized test covers ListType and StringType for resolved basic types
    • Existing microflow argument test preserved
    • Roundtrip audit verified fixes for real-world cases without regressions
  • Code changes are well-commented and maintain clear separation of concerns.
  • No modifications to MDL syntax, grammar, or AST were needed (pure executor fix).
  • Backend abstraction compliance maintained - no direct sdk/mpr imports in executor write paths.
  • The PR is tightly scoped to a single bug fix without extraneous changes.

Recommendation

Approve the PR. The fix is correct, well-tested, and maintains all existing behaviors while resolving the specific issue with typed Java action arguments. No changes are needed.


Automated review via OpenRouter (Nemotron Super 120B) — workflow source

@hjotha hjotha force-pushed the submit/empty-java-action-list-arg branch from 7b85f18 to d4b5776 Compare May 7, 2026 07:37
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 7, 2026

AI Code Review

What Looks Good

  • Clear problem/solution alignment: The PR precisely addresses the CE0126 "Missing value for parameter X" error by distinguishing between parameter types when emitting BSON for MDL empty literals.
  • Backward compatibility maintained: When jaDef == nil (no backend resolution), the original Argument: "" behavior is preserved to honor the "intentionally unbound" semantics documented in PROPOSAL_microflow_empty_java_action_argument.md.
  • Comprehensive test coverage: Added parametrized test covering ListType and StringType scenarios, while preserving existing tests for entity/microflow types and unresolved cases.
  • Clean implementation: The switch-based type classification is readable and extensible. Comments clearly explain the rationale for each branch.
  • No syntax changes: Since this is an internal fix to how existing MDL empty bindings are processed, no grammar/AST/LSP modifications were needed - correctly avoiding unnecessary changes.

Recommendation

Approve - The PR is correctly scoped, well-tested, maintains compatibility, and fixes the reported issue without introducing side effects. The implementation follows the project's patterns and the checklist requirements are satisfied for this type of internal bug fix.


Automated review via OpenRouter (Nemotron Super 120B) — workflow source

@github-actions github-actions Bot mentioned this pull request May 7, 2026
@ako
Copy link
Copy Markdown
Collaborator

ako commented May 7, 2026

Code Review

Correct and clean fix. The default: branch in the switch is the right approach — future BasicParameterType subtypes will automatically get the right behaviour without needing an explicit list. The jaDef == nil fallback to "" is well-reasoned.

Required before merge

  • No mdl-examples/bug-tests/521-*.mdl — checklist requires a bug-test script for every bug fix. A short script binding a ListType or String parameter to empty with a -- @expected: 0 errors annotation covers it.
  • .claude/skills/fix-issue.md symptom table not updated — CE0126 triggered by empty on a typed Java action parameter is a new entry for the symptom-to-layer-to-file mapping.

Minor

  • ParameterizedEntityType is called out in the PR description and roundtrip audit but not in the parametrized test. Since it falls into default: the logic is identical — a third case would complete the coverage for the types explicitly mentioned.
  • The comment block above resolvedBasicParams is thorough but could be trimmed to 2–3 lines; the full rationale is already in the proposal doc it cites.

hjothamendix and others added 3 commits May 8, 2026 10:02
When a Java action parameter is list-typed and the MDL author binds it
to `empty`, Studio Pro authors the BSON BasicCodeActionParameterValue
with Argument: "empty" — the literal MDL keyword. The current builder
collapses every empty primitive binding to Argument: "" (the unbound
marker), regardless of parameter type. For list-typed parameters that
substitution triggers `mx check` CE0126 "Missing value for parameter X"
because the model treats the parameter as missing rather than
explicitly empty.

Detect list-typed parameters via the Java action definition
(*javaactions.ListType) when looking up the action; for those
parameters bound to `empty` emit Argument: "empty". Primitive
parameters keep the existing blank-string behaviour. The describer
already maps both to the MDL `empty` keyword so round-trip stays
symmetric.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ameterType params

The original fix targeted only ListType parameters, but Studio Pro
authors `Argument: "empty"` for any typed BasicParameterType parameter
(String, Integer, Boolean, ParameterizedEntityType, ListType, …) when
the user explicitly binds it to MDL `empty`. Audit observations
surfaced two further cases beyond list-typed Tags: a microflow
parameter typed as `ParameterizedEntityType` and a Java action
parameter typed as `StringType`, both authored as `Argument: "empty"`
in real Studio Pro projects and both regressing to `Argument: ""`
under our previous fix — triggering the same `mx check` CE0126
"Missing value for parameter X" diagnostic.

Replace the listTypeParams set with resolvedBasicParams: when the
backend resolves a parameter whose type is anything OTHER than entity-
or microflow-type, the parameter goes into the
BasicCodeActionParameterValue branch and the MDL `empty` literal must
be preserved as `Argument: "empty"`. When jaDef is unavailable
(jaDef == nil) we keep the prior `""` behaviour to preserve the
documented "intentionally unbound" semantics of
PROPOSAL_microflow_empty_java_action_argument.md.

The unit test gains a String case alongside the List case — both must
emit `Argument: "empty"` once the parameter type is resolved.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@hjotha hjotha force-pushed the submit/empty-java-action-list-arg branch from d4b5776 to e6298e1 Compare May 8, 2026 08:02
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 8, 2026

AI Code Review

Critical Issues

None found.

Moderate Issues

None found.

Minor Issues

None found.

What Looks Good

  • Bug fix correctness: The PR correctly addresses the core issue where typed Java action parameters bound to empty were incorrectly emitting Argument: "" (unbound marker) instead of Argument: "empty" when the parameter type was resolvable via backend. The fix properly distinguishes between entity-type, microflow-type, and basic-type parameters.

  • Backend abstraction compliance: The change respects the backend abstraction layer - it only uses the resolved Java action definition (jaDef) when available and falls back to the original behavior when jaDef == nil, preserving the documented "intentionally unbound" semantics.

  • Test coverage:

    • New parametrized test TestBuildJavaAction_EmptyResolvedBasicArgumentEmitsEmptyKeyword covers ListType and StringType cases for resolved parameters
    • Existing tests are preserved and continue to pass
    • Roundtrip audit on 20-microflow sample verified no regressions
    • All tests pass per the PR description
  • Code quality:

    • Clear, well-commented code explaining the rationale
    • Minimal, focused change that doesn't mix concerns
    • Proper use of type switches for extensibility
    • Maintains existing behavior for edge cases (no backend, entity/microflow types)
  • Checklist adherence:

    • No syntax changes (so syntax design checks don't apply)
    • No duplication with existing implementations
    • Follows existing patterns in the codebase
    • Properly scoped to single concern
    • No security/robustness issues identified

Recommendation

Approve the PR. The fix is correct, well-tested, and maintains backward compatibility while resolving the reported issue with Java action argument handling. The change is minimal, focused, and follows all project conventions.


Automated review via OpenRouter (Nemotron Super 120B) — workflow source

Address PR mendixlabs#521 round-3 review (ako 2026-05-07).

- **`mdl-examples/bug-tests/521-empty-java-action-typed-arg.mdl`** — new
  bug-test calling a Java action with a list parameter and a string
  parameter, both bound to MDL `empty`. Before the fix this trips
  CE0126 "Missing value for parameter X"; after the fix, both slots
  serialise as `Argument: "empty"` and `mx check` reports 0 errors.

- **`.claude/skills/fix-issue.md`** — new symptom row mapping
  CE0126 on `call java action ... ($Param = empty)` to
  `addCallJavaActionAction` and the `resolvedBasicParams` fix pattern.
  Future contributors hitting the same symptom can land on the right
  file from the table without re-deriving the diagnosis.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 8, 2026

AI Code Review

Summary

The PR fixes a bug where call java action ... ($Param = empty) for typed parameters (BasicParameterType) incorrectly emitted Argument: "" instead of Argument: "empty", causing mx check CE0126 errors. The fix correctly distinguishes parameter types when the Java action definition is resolvable via backend, emitting "empty" for BasicParameterType parameters while preserving existing behavior for entity/microflow types and unresolved cases.

Critical Issues

None found.

Moderate Issues

None found.

Minor Issues

None found.

What Looks Good

  • Bug fix correctness: The change precisely targets the reported symptom (CE0126) by ensuring resolved BasicParameterType parameters emit Argument: "empty" for MDL empty literals.
  • Backward compatibility: Preserves Argument: "" behavior when jaDef == nil (unresolved action) to maintain documented "intentionally unbound" semantics.
  • Test coverage:
    • Adds new bug test script (521-empty-java-action-typed-arg.mdl) demonstrating the fix.
    • Adds parametrized unit test covering ListType and StringType cases.
    • Preserves all existing tests.
  • Documentation: Updates .claude/skills/fix-issue.md with the symptom/solution mapping.
  • Scope: Focused exclusively on the Java action parameter binding issue without unrelated changes.
  • Code quality: Clear comments explain the logic, follows existing patterns, and maintains deterministic behavior.

Recommendation

Approve - The PR is ready for merging. It correctly resolves the issue with appropriate test coverage, maintains backward compatibility, and follows project conventions. No changes needed.


Automated review via OpenRouter (Nemotron Super 120B) — workflow source

@hjotha
Copy link
Copy Markdown
Contributor Author

hjotha commented May 8, 2026

Thanks @ako — addressed in faee3363.

Required

  • mdl-examples/bug-tests/521-empty-java-action-typed-arg.mdl — new bug-test calls BugTest521.JA_ProcessBatch(Items = empty, Tag = empty) exercising both list-typed and string-typed BasicParameterType slots bound to MDL empty. Before the fix this trips CE0126 "Missing value for parameter X"; after the fix mx check reports 0 errors and both arguments serialise as Argument: "empty".
  • .claude/skills/fix-issue.md — new symptom row mapping CE0126 on call java action ... ($Param = empty) to addCallJavaActionAction and the resolvedBasicParams fix pattern. Future contributors hitting the same symptom can land on the right file directly.

@github-actions github-actions Bot mentioned this pull request May 8, 2026
@ako
Copy link
Copy Markdown
Collaborator

ako commented May 8, 2026

Updated Review

Both required items from the previous review are addressed:

  • Bug test521-empty-java-action-typed-arg.mdl added, covering ListType, StringType, and ParameterizedEntityType cases with clear symptom and validation steps.
  • fix-issue.md symptom table — CE0126 / typed Java action empty entry added with the full layer / file / remedy columns.

ParameterizedEntityType is still not in the Go parametrized test (still just list and string), but since the fix is handled by the default: branch the behaviour is identical — not a blocker.

Ready to merge.

@ako ako merged commit 2e80ca4 into mendixlabs:main May 8, 2026
1 of 2 checks passed
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 8, 2026

AI Code Review

Critical Issues

None found.

Moderate Issues

None found.

Minor Issues

None found.

What Looks Good

  • The PR correctly targets a specific bug (CE0126 on typed Java action parameters bound to empty) without over-scoping.
  • Changes are minimal and focused: only the Java action call builder logic is modified, with clear separation between resolved/unresolved backend cases.
  • Test coverage is excellent:
    • New bug test script reproduces the exact issue in MDL
    • New unit test verifies the BSON output for resolved basic parameters
    • Existing tests preserved and passing
    • Roundtrip audit confirms no regressions
  • Documentation updated in .claude/skills/fix-issue.md to help future debugging
  • Backward compatibility maintained: when jaDef == nil (no backend), preserves the original Argument: "" behavior for "intentionally unbound" semantics
  • Code follows existing patterns: uses same approach as entity/microflow type handling with clear comments
  • No syntax changes needed (fixes existing behavior), so full-stack consistency checklist doesn't apply

Recommendation

Approve the PR. It correctly fixes the reported issue with appropriate tests, maintains backward compatibility, and follows project conventions.


Automated review via OpenRouter (Nemotron Super 120B) — workflow source

@github-actions github-actions Bot mentioned this pull request May 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants