Skip to content

[15.x] Emit the context check for the containing type map in CollectionMapper - #4676

Merged
jbogard merged 2 commits into
release/15.xfrom
backport/15.x-collection-maxdepth-context
Nov 2, 2026
Merged

jbogard merged 2 commits into
release/15.xfrom
backport/15.x-collection-maxdepth-context

Conversation

@jbogard

@jbogard jbogard commented Oct 30, 2026

Copy link
Copy Markdown
Contributor

Backports #4651 (fixes #4650) and its follow-up regression test from #4675 (#4657) to release/15.x.

15.x has the automatic MaxDepth = 64 for self-referential type maps from the CVE-2026-32933 fix, but not the CollectionMapper context guard. As a result, ordinary Map<T>(source) calls can throw Context.Items are only available when using a Map overload that takes Action<IMappingOperationOptions>!, depending on registration or warmup order.

Both commits cherry-picked cleanly (-x):

  • CollectionMaxDepthContext and RegistrationOrderMaxDepthContext both fail on release/15.x before this change and pass after it.
  • Full unit test suite (net9.0): 1193 passed, 0 failed.

🤖 Generated with Claude Code

jbogard and others added 2 commits October 30, 2026 15:06
CollectionMapper emits the OverMaxDepth check from the containing type map
(memberMap.TypeMap) but decided whether to emit CheckContext from the element
type map. When the containing map has MaxDepth set and the element map is
plain, the generated plan calls context.OverTypeDepth against the default
context, which throws "Context.Items are only available when using a Map
overload that takes Action<IMappingOperationOptions>!".

Collection execution plans are cached per type pair and MapRequest equality
ignores MemberMap, so the first member map to compile a given collection pair
wins the cache for every other call site. Once a map with MaxDepth compiles
the plan, unrelated callers reaching it under the default context fail, which
makes the failure depend on warmup order rather than on configuration.

This became reachable for many more configurations when self-referential type
maps started defaulting to MaxDepth 64 in 0afaf1e.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wm2m61jXrAs4FheXR5TufH
(cherry picked from commit 179a97b)
…4657) (#4675)

Reproduces #4657, already fixed by #4651. Unlike that fix's test, this
needs no MapAtRuntime and a single Map call: cycle detection turns the
collection members into runtime calls, WorkItemModel.Stories compiles the
shared List<StoryEntity> -> List<StoryModel> plan with WorkItem's MaxDepth
check, and EpicModel.Stories then reuses it under the default context.
Registering InitiativeEntity -> InitiativeModel first is what makes the
Epic members runtime calls, so the test covers both registration orders.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit df65f2e)
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-30T20:08:03.952475Z 2c7dfe8 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@jbogard
jbogard merged commit fbe13ad into release/15.x Nov 2, 2026
3 checks passed
@jbogard
jbogard deleted the backport/15.x-collection-maxdepth-context branch November 2, 2026 14:48
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.

1 participant