Fix #519, #576, #696 + regression guards for #590, #608, #581, #606#729
Merged
Conversation
…uards for microsoft#590, microsoft#608, microsoft#581, microsoft#606 Code fixes: (common in custom actions that don't need config). Added null guards for both the context dict itself and each entry's value. ErrorMessage template was never interpolated into ExceptionMessage on the result tree (unlike ExecuteAllRulesAsync which formats correctly). Added the call. `$(input1.Inner.Name)` produced the raw JSON of `Inner` (`{"Name":"..."}`) instead of walking to the leaf. Rewrote UpdateErrorMessage to traverse the full path via JsonNode and emit the leaf scalar (unquoted) or nested JSON. Verified-already-fixed (regression tests added): run was fixed in commit 4ca3cc2 (microsoft#592). Test guards against regression. no longer reproduces — likely fixed by FastExpressionCompiler / Dynamic.Core version bumps. Test guards against regression. no longer reproduces, likely resolved by the AutoRegisterInputType work. Test guards against regression. mis-resolved on master — likely fixed by Dynamic.Core 1.4.3 → 1.6.7 bump. Test guards against regression. Not fixed in this PR: decision rather than a bug — ActionContext is documented as a static key/value config dict. Users who want evaluation should use OutputExpression. All 142 unit tests pass on net6 / net8 / net9 / net10.
e946047 to
5d73983
Compare
sagarambilpure
approved these changes
May 27, 2026
YogeshPraj
added a commit
that referenced
this pull request
May 27, 2026
Bump <Version> from 6.0.0 to 6.0.1-preview.1 and add a CHANGELOG entry covering the three PRs landed since 6.0.0: #727 (perf cache restore), #728 (action-exception propagation, list schema union, OutputExpression hint, global-param dedup, object-return diagnostics), and #729 (ExecuteActionWorkflowAsync FormatErrorMessages, ActionContext null guard, deep ErrorMessage interpolation, plus regression guards for #581, #590, #606, #608). Co-authored-by: Yogesh Prajapati <yogeshcprajapati@outlook.com>
This was referenced May 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Tier 2 follow-up to #727 (perf) and our batch-1 PR. Three real fixes, four already-fixed-on-main verifications turned into regression tests. Each fix has a dedicated test file.
Fixes #576 —
ActionContextctor NRE whenContextis nullActionContext's constructor unconditionally iteratescontextand dereferences eachkv.Value.GetType(). Custom actions that don't need configuration commonly leaveOnSuccess.Context = null, which crashed before the action could even run.Added a null guard on the dictionary itself and on each value. A null value now stores
nullin the internal map instead of throwing.Fixes #519 —
ExecuteActionWorkflowAsyncskippedFormatErrorMessagesExecuteAllRulesAsyncinterpolatesRule.ErrorMessage($(input.foo)) intoRuleResultTree.ExceptionMessageviaFormatErrorMessages.ExecuteActionWorkflowAsyncdid not, so users got an unpopulatedExceptionMessageon the same workflow.Added the call in
ExecuteActionWorkflowAsyncright before invoking the action. Result-tree shape and ordering are unchanged; onlyExceptionMessageis now populated consistently.Fixes #696 — Multi-level dotted
ErrorMessageinterpolationUpdateErrorMessagesplit the dotted path but only used segments[0](typeName) and[1](propertyName). For$([input1.Inner.Name](https://nam06.safelinks.protection.outlook.com/?url=http%3A%2F%2Finput1.inner.name%2F&data=05%7C02%7CYogesh.Prajapati%40microsoft.com%7C8276de067a704d3c502608debc07dec3%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C639154939190866661%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&sdata=mjtWuqX8oJIvyRkxLPcQCYkCg8c2bh%2Ffv%2BzGl88fcNw%3D&reserved=0))it settypeName=input1,propertyName=Inner— and then the replacement was the raw JSON ofInner({"Name":"deep-value"}) instead of"deep-value".Rewrote the helper to walk the full path via
JsonNode, returning the leaf scalar unquoted (forJsonValuestrings) or nested JSON otherwise. The single-level case is unchanged.Regression guards (verified already fixed on master)
4ca3cc2(PR #592)UseFastExpressionCompiler=true+ chained scoped-param sums NRE'dAutoRegisterInputTypework in PR #501lreported as unknown identifierEach repro from the linked issue now passes on master. Added explicit tests so we'd notice if any of these regressed.
Not fixed in this PR
#390 (ActionContext receives literal string instead of evaluated value) is a design decision rather than a bug —
ActionContextis documented as a static key/value config dict; users who want evaluation should useOutputExpression. Happy to revisit in a separate PR if the maintainers want to introduce a$(...)-evaluating mode.Test plan