Skip to content

Fix projection drops member fields with field middleware - #10048

Merged
michaelstaib merged 6 commits into
ChilliCream:mainfrom
PHILLIPS71:jp/projection-drops-member-fields-with-field-middleware
Jul 10, 2026
Merged

Fix projection drops member fields with field middleware#10048
michaelstaib merged 6 commits into
ChilliCream:mainfrom
PHILLIPS71:jp/projection-drops-member-fields-with-field-middleware

Conversation

@PHILLIPS71

Copy link
Copy Markdown
Contributor

Problem

SelectionExpressionBuilder.CollectSelection only projected fields with a pure resolver. Any middleware on a field removes its pure resolver, and one global UseField removes it from every field in the schema (ObjectField.IsPureContext).

With a global middleware registered, every selected field was silently dropped from QueryContext<T> and ISelection.AsSelector<T>() selectors. The builder fell back to the id-only selector (root => new Entity { Id = root.Id }), the database only fetched the id column, and every selected non-nullable field failed at runtime with HC0018. Nothing at schema build time or in the logs pointed at the middleware.

Fix

Purity decides how a field executes, not what data it needs. A member-bound resolver still reads the member when middleware wraps it, so the member still has to be projected. CollectSelection now accepts a field when its ResolverMember is declared on the parent runtime type, a base type, or an implemented interface. It no longer requires a pure resolver.

The other guards are unchanged. ResolveWith and extension resolvers stay excluded unless bound via [BindMember]. Method-inferred fields stay excluded by the PropertyInfo check. Connection and collection segment fields stay excluded.

One behavior change beyond the bug: member-declared fields with a custom Resolve(...) delegate now project the member even when the delegate is not pure. This over-fetches at most one column and never under-fetches. Pure custom delegates already behaved this way.

Test

GlobalFieldMiddlewareProjectionTests registers a pass-through UseField on a schema with a plain entity and asserts the captured selector binds the selected member. Without the fix the selector only binds Id and the request fails with HC0018.

@michaelstaib michaelstaib changed the title fix: projection drops member fields with field middleware Fix projection drops member fields with field middleware Jul 10, 2026
@michaelstaib
michaelstaib merged commit 88ef3ec into ChilliCream:main Jul 10, 2026
140 of 142 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants