Skip to content

Fix empty _source includes array returning all fields#20808

Closed
zheliu2 wants to merge 10 commits intoopensearch-project:mainfrom
zheliu2:fix/source-empty-includes-validation
Closed

Fix empty _source includes array returning all fields#20808
zheliu2 wants to merge 10 commits intoopensearch-project:mainfrom
zheliu2:fix/source-empty-includes-validation

Conversation

@zheliu2
Copy link
Copy Markdown
Contributor

@zheliu2 zheliu2 commented Mar 9, 2026

Summary

Fixes #20612

  • When _source includes is set to an empty array (e.g., "_source": [] or "_source": {"includes": []}), the expected behavior is to return an empty _source: {}. Previously, an empty includes array was treated the same as not setting includes at all, causing all source fields to be returned.
  • Added an includesExplicit flag to FetchSourceContext to distinguish between "no includes specified" (include everything) and "empty includes explicitly specified" (include nothing).
  • The flag is set during XContent parsing (fromXContent) and REST request parsing (parseFromRestRequest), and is propagated through wire serialization (version-gated to V_3_6_0) for cross-node compatibility.

Changes

  • FetchSourceContext.java: Added includesExplicit boolean field, private 4-arg constructor, version-gated serialization, and filter logic that returns an empty map when includes is explicitly empty.
  • FetchSourcePhase.java: Updated containsFilters() to recognize explicitly empty includes as a filter.
  • FetchSourcePhaseTests.java: Added testEmptyIncludesArray and testEmptyIncludesWithExcludes test cases.

Test plan

  • FetchSourcePhaseTests.testEmptyIncludesArray - verifies _source: [] and _source: {"includes": []} both return empty source
  • FetchSourcePhaseTests.testEmptyIncludesWithExcludes - verifies _source: {"includes": [], "excludes": ["field1"]} returns empty source
  • All existing FetchSourcePhaseTests continue to pass

@github-actions github-actions bot added enhancement Enhancement or improvement to existing feature or request good first issue Good for newcomers Search:Query Insights labels Mar 9, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 9, 2026

PR Reviewer Guide 🔍

(Review updated until commit 66a9ba0)

Here are some key observations to aid the review process:

🧪 PR contains tests
🔒 No security concerns identified
✅ No TODO sections
🔀 Multiple PR themes

Sub-PR theme: Fix empty _source includes returning all fields (core logic)

Relevant files:

  • server/src/main/java/org/opensearch/search/fetch/subphase/FetchSourceContext.java
  • server/src/main/java/org/opensearch/search/fetch/subphase/FetchSourcePhase.java

Sub-PR theme: Add tests for empty includes array behavior

Relevant files:

  • server/src/test/java/org/opensearch/search/fetch/subphase/FetchSourcePhaseTests.java

⚡ Recommended focus areas for review

Immutable Filter Cache

The filter field is lazily initialized and cached. However, since FetchSourceContext instances like FETCH_SOURCE and DO_NOT_FETCH_SOURCE are shared static constants, and filter is not volatile or synchronized, there could be a race condition in multi-threaded environments when getFilter() is called concurrently. The existing code had this same issue, but the new branch adds another code path that makes this more prominent.

public Function<Map<String, ?>, Map<String, Object>> getFilter() {
    if (filter == null) {
        // If includes was explicitly set to an empty array, return an empty map
        // rather than treating it as "include everything"
        if (includesExplicit && includes.length == 0) {
            filter = (sourceAsMap) -> Collections.emptyMap();
        } else {
            filter = XContentMapValues.filter(includes, excludes, true);
        }
    }
    return filter;
}
Serialization Compatibility

The version gate uses Version.V_3_6_0 for the new includesExplicit field. If this fix needs to be backported to earlier minor versions (e.g., 2.x), the version constant would need to be adjusted. Additionally, when communicating with nodes on older versions, includesExplicit will always be false, meaning the empty-includes fix will silently not work in mixed-version clusters until all nodes are upgraded.

if (in.getVersion().onOrAfter(Version.V_3_6_0)) {
    includesExplicit = in.readBoolean();
} else {
    includesExplicit = false;
}
REST Request Empty String

In parseFromRestRequest, when _source_includes is set to an empty string (e.g., _source_includes=), Strings.splitStringByCommaToArray("") may return an empty array, and includesExplicit will be set to true. This could unintentionally trigger the "return empty source" behavior when the user simply omitted the parameter value rather than explicitly requesting empty includes.

String sIncludes = request.param("_source_includes");
if (sIncludes != null) {
    sourceIncludes = Strings.splitStringByCommaToArray(sIncludes);
    includesExplicit = true;
Incomplete Test Coverage

The new hitExecuteWithContext helper method has a conditional that only calls processor.process() when fetchSource() is true, but does not assert that the processor is null when fetchSource() is false. This differs from the existing hitExecuteMultiple helper which explicitly asserts null/non-null. Also, there are no tests covering the REST request parsing path (parseFromRestRequest) for the empty includes scenario.

if (fetchSourceContext.fetchSource()) {
    assertNotNull(processor);
    processor.process(hitContext);
} else {
    assertNull(processor);
}

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 9, 2026

PR Code Suggestions ✨

Latest suggestions up to 66a9ba0

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Detect explicit empty includes in public constructor

The public constructor always sets includesExplicit = false, meaning callers who
pass a non-null empty includes array directly via this constructor will not get the
"empty includes means nothing" behavior. This is a silent behavioral inconsistency —
passing new String[0] vs null as includes will behave the same. Consider whether the
public constructor should detect a non-null empty array and set includesExplicit =
true accordingly.

server/src/main/java/org/opensearch/search/fetch/subphase/FetchSourceContext.java [77-82]

 public FetchSourceContext(boolean fetchSource, String[] includes, String[] excludes) {
     this.fetchSource = fetchSource;
     this.includes = includes == null ? Strings.EMPTY_ARRAY : includes;
     this.excludes = excludes == null ? Strings.EMPTY_ARRAY : excludes;
-    this.includesExplicit = false;
+    this.includesExplicit = includes != null;
 }
Suggestion importance[1-10]: 6

__

Why: This is a valid behavioral inconsistency — callers passing new String[0] vs null to the public constructor will get different behavior silently. Setting includesExplicit = includes != null would make the constructor semantics more intuitive and consistent with the rest of the implementation.

Low
General
Guard against blank includes parameter setting explicit flag

When _source_excludes is provided without any includes parameter, includesExplicit
remains false, which is correct. However, if _source_includes is set to an empty
string via the REST parameter, Strings.splitStringByCommaToArray("") may return a
non-null but empty array, and includesExplicit would be set to true. This could
cause all fields to be excluded when the user just passed an empty _source_includes
parameter accidentally. Consider checking that sIncludes is not blank before setting
includesExplicit.

server/src/main/java/org/opensearch/search/fetch/subphase/FetchSourceContext.java [155-158]

-if (fetchSource != null || sourceIncludes != null || sourceExcludes != null) {
-    return new FetchSourceContext(fetchSource == null ? true : fetchSource, sourceIncludes, sourceExcludes, includesExplicit);
+String sIncludes = request.param("_source_includes");
+if (sIncludes != null && !sIncludes.isBlank()) {
+    sourceIncludes = Strings.splitStringByCommaToArray(sIncludes);
+    includesExplicit = true;
+} else if (sIncludes != null) {
+    sourceIncludes = Strings.splitStringByCommaToArray(sIncludes);
 }
-return null;
Suggestion importance[1-10]: 5

__

Why: This is a valid edge case concern — passing an empty _source_includes parameter could unintentionally set includesExplicit = true and return an empty map. The suggestion addresses a potential behavioral issue, though it's an edge case that may not occur in practice.

Low
Document empty-includes behavior with excludes present

When includesExplicit is true and includes is empty but excludes is non-empty, the
current code still returns an empty map, ignoring the excludes. While this may be
intentional (empty includes means nothing is included), it could lead to unexpected
behavior. Consider documenting this explicitly or handling the case where excludes
are provided alongside an empty includes array.

server/src/main/java/org/opensearch/search/fetch/subphase/FetchSourceContext.java [314-318]

+// If includes was explicitly set to an empty array, return an empty map
+// regardless of excludes, since there's nothing to include
 if (includesExplicit && includes.length == 0) {
     filter = (sourceAsMap) -> Collections.emptyMap();
 } else {
     filter = XContentMapValues.filter(includes, excludes, true);
 }
Suggestion importance[1-10]: 2

__

Why: The suggestion only proposes adding a comment to document existing behavior, which is a minor documentation improvement. The improved_code is essentially the same logic as existing_code with just a comment change, making this a very low-impact suggestion.

Low

Previous suggestions

Suggestions up to commit 09e1fd2
CategorySuggestion                                                                                                                                    Impact
General
Document empty-includes-with-excludes behavior explicitly

When includesExplicit is true and includes is empty, the filter ignores any excludes
that may also be set. While the test testEmptyIncludesWithExcludes asserts empty map
is returned, this silently discards excludes. The behavior is consistent, but the
empty-includes-with-excludes case may warrant a comment or explicit handling to
avoid future confusion. More critically, the filter field is lazily initialized but
not thread-safe — if getFilter() is called concurrently, two different lambdas could
be assigned. Consider making filter volatile or computing it eagerly.

server/src/main/java/org/opensearch/search/fetch/subphase/FetchSourceContext.java [314-318]

 if (includesExplicit && includes.length == 0) {
+    // Empty includes explicitly set means include nothing, regardless of excludes
     filter = (sourceAsMap) -> Collections.emptyMap();
 } else {
     filter = XContentMapValues.filter(includes, excludes, true);
 }
Suggestion importance[1-10]: 2

__

Why: The suggestion only adds a comment to clarify behavior, which is a minor documentation improvement. The existing code comment already partially explains the logic, and the improved_code is nearly identical to existing_code with just a comment change.

Low
Simplify filter detection condition ordering

When includesExplicit() is true and includes is empty, containsFilters returns true,
which correctly triggers the filter path. However, context.includes().length != 0 is
already false in that case, so context.includesExplicit() alone covers the
empty-includes case. But note that includesExplicit() being true also implies
includes.length could be non-zero (already covered by the first condition), making
the check slightly redundant for non-empty cases. The logic is correct but could be
simplified to context.includesExplicit() || context.excludes().length != 0 since
includesExplicit is true whenever includes are set (empty or not).

server/src/main/java/org/opensearch/search/fetch/subphase/FetchSourcePhase.java [127]

-return context.includes().length != 0 || context.excludes().length != 0 || context.includesExplicit();
+return context.includesExplicit() || context.includes().length != 0 || context.excludes().length != 0;
Suggestion importance[1-10]: 2

__

Why: The suggestion reorders conditions but the logic remains equivalent since includesExplicit being true doesn't strictly imply includes.length != 0 (it can be true with empty includes). The reordering doesn't simplify the logic as claimed and the improved_code is functionally identical to existing_code.

Low
Clarify intent of includesExplicit flag in REST parsing

When _source_excludes is provided without any includes parameter, includesExplicit
remains false and sourceIncludes is null. This is correct. However, if only
_source_excludes is set, the condition sourceIncludes != null is false but
sourceExcludes != null is true, so a context is returned with
includesExplicit=false. This is the intended behavior, but it means includesExplicit
is only set when _source_includes or _source (non-boolean) is explicitly provided —
which is correct. The logic is fine, but consider adding a comment to clarify why
includesExplicit is not set when only excludes are specified.

server/src/main/java/org/opensearch/search/fetch/subphase/FetchSourceContext.java [166-169]

 if (fetchSource != null || sourceIncludes != null || sourceExcludes != null) {
+    // includesExplicit is only true when _source_includes or _source (as field list) was explicitly provided
     return new FetchSourceContext(fetchSource == null ? true : fetchSource, sourceIncludes, sourceExcludes, includesExplicit);
 }
 return null;
Suggestion importance[1-10]: 1

__

Why: This suggestion only adds a comment to the existing code without any functional change. The improved_code is functionally identical to existing_code, making this a purely cosmetic documentation suggestion.

Low
Suggestions up to commit a71032d
CategorySuggestion                                                                                                                                    Impact
Possible issue
Guard against empty string param setting explicit flag

When _source_includes is an empty string parameter (e.g., _source_includes=),
Strings.splitStringByCommaToArray may return an empty array, setting
includesExplicit = true and sourceIncludes to an empty array. This would cause
getFilter() to return an empty map even though the user likely didn't intend to
exclude all fields. Consider checking that sIncludes is non-empty before setting
includesExplicit = true.

server/src/main/java/org/opensearch/search/fetch/subphase/FetchSourceContext.java [155-159]

-if (fetchSource != null || sourceIncludes != null || sourceExcludes != null) {
-    return new FetchSourceContext(fetchSource == null ? true : fetchSource, sourceIncludes, sourceExcludes, includesExplicit);
+String sIncludes = request.param("_source_includes");
+if (sIncludes != null && !sIncludes.isEmpty()) {
+    sourceIncludes = Strings.splitStringByCommaToArray(sIncludes);
+    includesExplicit = true;
 }
-return null;
Suggestion importance[1-10]: 5

__

Why: This is a valid edge case concern — passing an empty _source_includes= parameter could unintentionally set includesExplicit = true and return an empty map. The fix is reasonable, though the scenario may be rare in practice.

Low
General
Reconsider metadata field impact on equality

Including includesExplicit in equals and hashCode means two FetchSourceContext
objects with identical fetchSource, includes, and excludes values but different
includesExplicit flags will be considered unequal. This could break caching or
deduplication logic that relies on equality. Consider whether includesExplicit
should affect equality, or if it should be treated as metadata that doesn't affect
the logical identity of the context.

server/src/main/java/org/opensearch/search/fetch/subphase/FetchSourceContext.java [283-295]

 public boolean equals(Object o) {
     if (this == o) return true;
     if (o == null || getClass() != o.getClass()) return false;
 
     FetchSourceContext that = (FetchSourceContext) o;
 
     if (fetchSource != that.fetchSource) return false;
-    if (includesExplicit != that.includesExplicit) return false;
     if (!Arrays.equals(excludes, that.excludes)) return false;
     if (!Arrays.equals(includes, that.includes)) return false;
+    // Note: includesExplicit is intentionally included to distinguish
+    // empty-includes-explicit from no-includes-specified
+    if (includesExplicit != that.includesExplicit) return false;
 
     return true;
 }
Suggestion importance[1-10]: 4

__

Why: The concern about includesExplicit affecting equality and potentially breaking caching is valid, but the improved_code still includes includesExplicit in the equality check (just reordered with a comment), making it functionally identical to the existing code. The suggestion raises a legitimate design question but doesn't actually implement the proposed change.

Low
Document intentional exclusion of excludes filter

When includesExplicit is true and includes is empty, the excludes array is
completely ignored. If a user specifies {"includes": [], "excludes": ["field1"]},
the excludes are silently discarded. The current behavior is documented in the test
testEmptyIncludesWithExcludes, but this may be surprising. More importantly, if
includesExplicit is true but includes is non-empty, the excludes are still applied
correctly — so the asymmetry only exists for the empty-includes case, which is
intentional. However, the filter lambda ignores excludes entirely, which could be a
semantic issue worth documenting or asserting.

server/src/main/java/org/opensearch/search/fetch/subphase/FetchSourceContext.java [314-318]

 if (includesExplicit && includes.length == 0) {
+    // Empty includes explicitly set means include nothing, excludes are irrelevant
     filter = (sourceAsMap) -> Collections.emptyMap();
 } else {
     filter = XContentMapValues.filter(includes, excludes, true);
 }
Suggestion importance[1-10]: 2

__

Why: The suggestion only proposes adding a comment to document existing behavior. The improved_code is functionally identical to the existing_code, just with an added comment. This is a documentation-only change with minimal impact.

Low
Suggestions up to commit 1832da4
CategorySuggestion                                                                                                                                    Impact
Possible issue
Infer explicit flag from constructor argument

The public constructor always sets includesExplicit = false, meaning callers who
pass a non-null (even empty) includes array will not have includesExplicit set to
true. This could lead to the bug recurring if code constructs a FetchSourceContext
with an explicit empty includes array using the public constructor. Consider setting
includesExplicit = (includes != null) in the public constructor to correctly reflect
whether includes was explicitly provided.

server/src/main/java/org/opensearch/search/fetch/subphase/FetchSourceContext.java [77-82]

 public FetchSourceContext(boolean fetchSource, String[] includes, String[] excludes) {
     this.fetchSource = fetchSource;
     this.includes = includes == null ? Strings.EMPTY_ARRAY : includes;
     this.excludes = excludes == null ? Strings.EMPTY_ARRAY : excludes;
-    this.includesExplicit = false;
+    this.includesExplicit = (includes != null);
 }
Suggestion importance[1-10]: 6

__

Why: This is a valid concern — the public constructor always sets includesExplicit = false, so callers passing an explicit empty includes array won't get the correct behavior. Setting includesExplicit = (includes != null) would make the public constructor consistent with the intent of the feature and prevent the bug from recurring through direct constructor usage.

Low
General
Reconsider including flag in equality check

Including includesExplicit in equals() and hashCode() may cause issues when
comparing two FetchSourceContext objects that are semantically equivalent (same
includes/excludes arrays) but differ only in how they were constructed. For example,
a context with an empty includes array set explicitly vs. one deserialized from an
older node (where includesExplicit defaults to false) would not be considered equal,
potentially causing cache misses or unexpected behavior. Consider whether
includesExplicit should influence equality or only affect the filter behavior.

server/src/main/java/org/opensearch/search/fetch/subphase/FetchSourceContext.java [289-292]

 if (fetchSource != that.fetchSource) return false;
-if (includesExplicit != that.includesExplicit) return false;
 if (!Arrays.equals(excludes, that.excludes)) return false;
 if (!Arrays.equals(includes, that.includes)) return false;
Suggestion importance[1-10]: 4

__

Why: The suggestion raises a valid concern about cross-version equality issues where includesExplicit defaults to false for older nodes. However, the improved_code removes includesExplicit from equals() entirely, which would break the semantic distinction the PR is trying to establish. The concern is real but the proposed fix is too aggressive.

Low
Add clarifying comment for flag semantics

When _source_excludes is provided without any includes parameter, includesExplicit
remains false but sourceExcludes != null triggers context creation. This is correct.
However, if only _source_excludes is provided, the includesExplicit flag is false
and sourceIncludes is null, which means the public constructor sets includes to
EMPTY_ARRAY with includesExplicit=false — this is the correct "include everything"
behavior. The logic appears correct, but it's worth adding a comment to clarify this
intentional distinction for future maintainers.

server/src/main/java/org/opensearch/search/fetch/subphase/FetchSourceContext.java [166-169]

 if (fetchSource != null || sourceIncludes != null || sourceExcludes != null) {
+    // includesExplicit is true only when _source or _source_includes was explicitly provided as a filter,
+    // not when only _source_excludes was specified (which means "include everything except...")
     return new FetchSourceContext(fetchSource == null ? true : fetchSource, sourceIncludes, sourceExcludes, includesExplicit);
 }
 return null;
Suggestion importance[1-10]: 1

__

Why: This suggestion only adds a comment to clarify existing behavior without changing any logic. The improved_code is functionally identical to existing_code, making this a documentation-only suggestion with minimal impact.

Low
Suggestions up to commit 576bca2
CategorySuggestion                                                                                                                                    Impact
General
Reconsider equality semantics with new flag

Including includesExplicit in equals() and hashCode() means that two
FetchSourceContext objects with identical fetchSource, includes, and excludes values
but different includesExplicit flags will not be considered equal. This could break
caching or deduplication logic that previously treated these as equivalent. Consider
whether includesExplicit should affect equality or only affect the filter behavior.

server/src/main/java/org/opensearch/search/fetch/subphase/FetchSourceContext.java [289-292]

+if (fetchSource != that.fetchSource) return false;
+if (includesExplicit != that.includesExplicit) return false;
+if (!Arrays.equals(excludes, that.excludes)) return false;
+if (!Arrays.equals(includes, that.includes)) return false;
 
-
Suggestion importance[1-10]: 5

__

Why: This raises a valid concern about including includesExplicit in equals() and hashCode(), which could break caching or deduplication logic. However, the existing_code and improved_code are identical, so no concrete fix is proposed.

Low
Document empty-includes behavior with excludes

When includesExplicit is true and includes is empty but excludes is non-empty, the
current logic still returns an empty map, ignoring the excludes entirely. While the
test testEmptyIncludesWithExcludes asserts this behavior, it may be surprising and
inconsistent. Consider documenting this explicitly or evaluating whether excludes
should be applied even when includes is empty.

server/src/main/java/org/opensearch/search/fetch/subphase/FetchSourceContext.java [314-318]

+// If includes was explicitly set to an empty array, return an empty map
+// rather than treating it as "include everything".
+// Note: excludes are intentionally ignored when includes is explicitly empty,
+// since there is nothing to exclude from an already-empty result set.
 if (includesExplicit && includes.length == 0) {
     filter = (sourceAsMap) -> Collections.emptyMap();
 } else {
     filter = XContentMapValues.filter(includes, excludes, true);
 }
Suggestion importance[1-10]: 2

__

Why: The suggestion only proposes adding comments to document existing behavior. The existing_code and improved_code are functionally identical, differing only in comment text. This is a documentation-only change with minimal impact.

Low
Verify null includes vs explicit empty includes distinction

When _source_excludes is provided without any includes parameter, includesExplicit
remains false, which is correct. However, if sourceIncludes is null and
includesExplicit is false, the private constructor still sets includes to
Strings.EMPTY_ARRAY, which could be misinterpreted as an explicit empty includes.
This is consistent with the existing behavior, but it's worth verifying that
includesExplicit=false with an empty includes array correctly falls through to
XContentMapValues.filter (include everything), which it does based on the
getFilter() logic.

server/src/main/java/org/opensearch/search/fetch/subphase/FetchSourceContext.java [166-169]

+if (fetchSource != null || sourceIncludes != null || sourceExcludes != null) {
+    return new FetchSourceContext(fetchSource == null ? true : fetchSource, sourceIncludes, sourceExcludes, includesExplicit);
+}
+return null;
 
-
Suggestion importance[1-10]: 1

__

Why: The existing_code and improved_code are identical, making this a verification-only suggestion with no actual code change. The logic is already correct as described.

Low
Suggestions up to commit b97be52
CategorySuggestion                                                                                                                                    Impact
General
Reconsider including flag in equality comparison

Including includesExplicit in equals and hashCode means that two FetchSourceContext
objects with the same fetchSource, includes, and excludes values but different
includesExplicit flags will be considered unequal. This could cause issues in
caching or deduplication scenarios where the same logical filter should be treated
as equal. Consider whether includesExplicit should be part of equality or only
affect the getFilter() behavior.

server/src/main/java/org/opensearch/search/fetch/subphase/FetchSourceContext.java [283-295]

+public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
 
+    FetchSourceContext that = (FetchSourceContext) o;
 
+    if (fetchSource != that.fetchSource) return false;
+    if (includesExplicit != that.includesExplicit) return false;
+    if (!Arrays.equals(excludes, that.excludes)) return false;
+    if (!Arrays.equals(includes, that.includes)) return false;
+
+    return true;
+}
+
Suggestion importance[1-10]: 4

__

Why: The existing_code and improved_code are identical, so no actual code change is proposed. However, the concern raised is valid — including includesExplicit in equals/hashCode means two contexts with the same arrays but different explicit flags are unequal, which could affect caching. This is a legitimate design concern worth considering, but since no concrete fix is provided, the score is limited.

Low
Document intentional behavior of empty includes ignoring excludes

When includesExplicit is true and includes is empty, the filter ignores any excludes
that may have been set. While the test testEmptyIncludesWithExcludes asserts an
empty map is returned, this silently discards the excludes configuration. The
behavior is consistent but the excludes are effectively ignored without any
indication. Consider documenting this explicitly or ensuring the logic is
intentional and consistent with the expected contract.

server/src/main/java/org/opensearch/search/fetch/subphase/FetchSourceContext.java [314-318]

 if (includesExplicit && includes.length == 0) {
+    // Empty includes explicitly set means include nothing, excludes are irrelevant
     filter = (sourceAsMap) -> Collections.emptyMap();
 } else {
     filter = XContentMapValues.filter(includes, excludes, true);
 }
Suggestion importance[1-10]: 1

__

Why: The suggestion only proposes adding a comment to document existing behavior. The existing_code and improved_code are functionally identical, differing only in a comment addition. This is a documentation-only change with minimal impact.

Low

…ject#20612)

When _source includes is set to an empty array (e.g., "_source": [] or
"_source": {"includes": []}), the expected behavior is to return an
empty _source object {}. Previously, an empty includes array was treated
the same as not setting includes at all, causing all source fields to be
returned.

This fix adds an includesExplicit flag to FetchSourceContext to
distinguish between "no includes specified" (include everything) and
"empty includes explicitly specified" (include nothing). The flag is
set during XContent parsing and REST request parsing, and is propagated
through wire serialization for cross-node compatibility.

Signed-off-by: zheliu2 <770120041@qq.com>
@zheliu2 zheliu2 force-pushed the fix/source-empty-includes-validation branch from db9f7d9 to 702cc79 Compare March 9, 2026 16:25
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 9, 2026

Persistent review updated to latest commit 702cc79

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 9, 2026

❌ Gradle check result for 702cc79: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

Signed-off-by: zheliu2 <770120041@qq.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 9, 2026

Persistent review updated to latest commit 6773b61

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 9, 2026

❌ Gradle check result for 6773b61: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

Signed-off-by: zheliu2 <770120041@qq.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 9, 2026

Persistent review updated to latest commit b6ee433

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 9, 2026

❌ Gradle check result for b6ee433: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

Signed-off-by: zheliu2 <770120041@qq.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 9, 2026

Persistent review updated to latest commit b97be52

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 9, 2026

❌ Gradle check result for b97be52: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

zheliu2 added 2 commits March 9, 2026 14:57
Signed-off-by: zheliu2 <770120041@qq.com>
Signed-off-by: zheliu2 <770120041@qq.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 9, 2026

Persistent review updated to latest commit 576bca2

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 9, 2026

❌ Gradle check result for 576bca2: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

Signed-off-by: zheliu2 <770120041@qq.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 9, 2026

Persistent review updated to latest commit 1832da4

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 9, 2026

❌ Gradle check result for 1832da4: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

Signed-off-by: zheliu2 <770120041@qq.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 9, 2026

Persistent review updated to latest commit a71032d

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 9, 2026

❌ Gradle check result for a71032d: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

Signed-off-by: zheliu2 <770120041@qq.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 9, 2026

Persistent review updated to latest commit 09e1fd2

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 9, 2026

❌ Gradle check result for 09e1fd2: FAILURE

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

Signed-off-by: zheliu2 <770120041@qq.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 9, 2026

Persistent review updated to latest commit 66a9ba0

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 9, 2026

❌ Gradle check result for 66a9ba0: null

Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change?

@zheliu2
Copy link
Copy Markdown
Contributor Author

zheliu2 commented Mar 10, 2026

Closing — CI gradle-check is consistently failing due to Jenkins infrastructure issues. Will reopen or recreate if needed.

@zheliu2 zheliu2 closed this Mar 10, 2026
@urmichm
Copy link
Copy Markdown
Contributor

urmichm commented Mar 13, 2026

Hi @zheliu2
This is a duplicate of an existing issue with a prepared PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Enhancement or improvement to existing feature or request good first issue Good for newcomers Search:Query Insights

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request] [BUG] _source include / exclude validation

2 participants