Skip to content

Microflow roundtrip: REST call with retry-loop error handler loses main-path variable scope (CE0108) #506

@hjotha

Description

@hjotha

Summary

When a rest call (or other call activity) has a custom error handler of the shape on error without rollback { ... ; if <retry> then ... else raise end if } and is followed by activities that reference the call's output variable, the roundtrip produces an MPR that fails mx check with CE0108 "Variable X is defined but not in scope". The authored (Studio Pro) topology uses a loop-back edge from the error handler's non-terminating branch back to a merge placed before the source activity to implement retry semantics; MDL does not have syntax to express this, so the builder emits a linear topology that changes variable scope.

Reproduction

# base MPR: any project containing the microflow below
mxcli exec -p app.mpr retry_microflow.mdl
mx check app.mpr   # [error] [CE0108] "Variable 'X' is defined but not in scope at this location."

Minimal reproducing MDL:

create or modify microflow M.Retry ($In: String) returns String begin
  declare $RetryCount Integer = 0;
  $R = call microflow M.Helper(...) on error without rollback {
    log error node @M.LogNode 'retry';
    if $RetryCount<1 then
      set $RetryCount = $RetryCount+1;
    else
      raise error;
    end if;
  };
  retrieve $Items from $R/M.Items_R;   -- CE0108: $R out of scope
  return $In;
end;
/

Root cause

The authored BSON has a merge node placed before the source call, with the retry branch of the error handler flowing back to it:

prev → MERGE ────┐
                 ↓
              sourceCall
                 ↓
              (happy-path continues)
                 ↑
sourceCall ─err→ Log → Split ─true→ Log → Java → ChangeVar ─┘ (loops back to MERGE)
                          └─false→ ErrorEvent

The builder currently reads MDL and produces a linear topology that places the merge between the two downstream activities, moving the call's output variable out of scope for subsequent activities.

Why MDL can't express this today

MDL assumes the error handler is a forward flow: after the handler runs, execution continues to whatever activity follows the source. There is no syntax for "re-execute activity N" or "jump back to merge point M". Studio Pro authors draw the loop-back as a free-form sequence flow that has no surface syntax in MDL.

Scope

  • Reproducible against origin/main with no open PRs applied — not a regression introduced by recent PRs.
  • Hits any microflow with a call activity carrying a custom error handler of the retry-loop shape described above.

Possible approaches

  1. Detect and wire the loop-back in the builder (smallest change): when the error handler body ends with an IF where exactly one branch terminates, the builder inserts a merge before the source and wires the non-terminating branch's tail back to that merge. No MDL syntax changes.
  2. New MDL syntax (larger change): retry on error { ... } as an explicit retry-loop construct. The describer detects the authored topology and emits the new syntax.
  3. Round-trip allowlist: document the shape as unsupported and filter it out of audit regressions.

Recommend option 1 as an immediate fix. See PR #507.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions