A javadoc example that shows how to add a suggestion with contexts calls the constructor with its arguments in the wrong order.
ContextSuggestFieldindexes a suggestion (a string and an integer weight) together with one or more context strings, for the document suggester inlucene-suggest.- At query time a
ContextQuerywraps a completion query such as aPrefixCompletionQueryand keeps (or boosts) only suggestions with the given contexts; hits are scored by weight.
ContextSuggestField javadoc example next to the only constructor: the contexts List sits where the int weight goes, the one javac error it causes, why no release ever had a matching constructor, and the corrected call returning "suggestion" with score 4 for context1. Select the still to open it at full size. Generated with AI, checked against the code.- You want suggestions filtered by context, so you copy the example from the
ContextSuggestFieldclass javadoc:document.add(new ContextSuggestField(name, "suggestion", Arrays.asList("context1", "context2"), 4));, the suggestion "suggestion" with weight 4 and two contexts. - You expect it to compile and, with a second document ("suggestive", weight 2, context3) in the index, a
ContextQueryfor prefix "sugg" on context1 to return 1 hit: "suggestion" with score 4. - Instead javac stops with 1 error, on every release from 5.3.0 to 10.6.0 and on main: "incompatible types: no instance(s) of type variable(s) T exist so that List<T> conforms to int".
- Why: the only constructor is
ContextSuggestField(String name, String value, int weight, CharSequence... contexts). The example puts theListwhere theint weightgoes. No constructor ever took that order: the example was already wrong when it was added in 2015, and a cleanup five days later moved to varargs without updating it. - Fix: write
new ContextSuggestField(name, "suggestion", 4, "context1", "context2"). It compiles, and the context1 query returns "suggestion" with score 4.
Developers who add context-aware suggestions with the lucene-suggest document suggester (an @lucene.experimental API) and copy the class's only example, on any release from 5.3.0 or main. Nothing wrong ever runs: javac refuses the line, and the constructor javadoc just below has the right order. Low impact, but plainly wrong.
Mechanism, terms and numbers386 words
The class javadoc of org.apache.lucene.search.suggest.document.ContextSuggestField has one example, "Example usage of adding a suggestion with contexts is as follows:" (ContextSuggestField.java:32-37 on main 645d4fe14a20): document.add(new ContextSuggestField(name, "suggestion", Arrays.asList("context1", "context2"), 4));. Copied into code, that call does not compile on any release (5.3.0 to 10.6.0) or on main. The only constructor is ContextSuggestField(String name, String value, int weight, CharSequence... contexts) (:65), so javac tries to pass the List as the int weight and reports "incompatible types: no instance(s) of type variable(s) T exist so that List<T> conforms to int". No constructor has ever accepted the example's (name, value, List, weight) order: LUCENE-6459 (2015-05-28) wrote it against a (name, Collection, value, weight) constructor, and LUCENE-6515 (2015-06-02) changed the constructor to the varargs form on purpose without touching the example; both first shipped in 5.3.0. In constructor order, new ContextSuggestField(name, "suggestion", 4, "context1", "context2"), it compiles, and a ContextQuery on context1 returns suggestion with weight 4. No runtime code is wrong.
// Example usage of adding a suggestion with contexts is as follows:
document.add(
new ContextSuggestField(name, "suggestion", Arrays.asList("context1", "context2"), 4));ContextSuggestField.java:65: the only constructor ispublic ContextSuggestField(String name, String value, int weight, CharSequence... contexts). Its own javadoc (:55-64) lists@param name,value,weight,contextsin that order.- The example's arguments are
(String, String, List<String>, int). With the varargs, four arguments fit(name, value, weight, one context), so javac tries to passArrays.asList("context1", "context2")as theint weightand reportsincompatible types: no instance(s) of type variable(s) T exist so that List<T> conforms to int. The default message namesint, not the argument order; only with-Xdiags:verbosedoes javac listrequired: String,String,int,CharSequence[]againstfound: String,String,List<String>,int. - No build ever had a constructor in the example's order: a class-file scan of 158 builds (1.9.1 to main; no suggest jar was cached for the 26 builds up to 3.6.2, long before the class existed) finds only
(String, String, int, CharSequence[])from 5.3.0 on.
No current build task compiles ordinary <pre> code blocks in javadoc: renderJavadoc, ECJ lint and the missing-javadoc check run, but none compiles this block. The open issue #9534 (LUCENE-8488) asks for compile-checked javadoc examples in general.
Exposure and likelihood110 words
- Who is hit. Anyone who copies the only code example in the
ContextSuggestFieldclass javadoc to index a suggestion with contexts. The class is@lucene.experimental(ContextSuggestField.java:44). - Default vs opt-in. Not a configuration matter: every copy fails, on every release that has the class (5.3.0 to 10.6.0, 104 releases) and on main.
- Scale. One line, one compile error. The constructor javadoc a few lines below lists the right order, but javac's message ("List<T> conforms to int") does not say the order is the problem.
- What it does not do. No wrong results, no runtime path, no index change. The constructor, its javadoc and context indexing and querying are right.
One JUnit test compiles the example's two lines, copied verbatim, with the JDK's compiler against the test's own class path. It adds only imports, the free names document and name as method parameters, and a small wrapper class. Deterministic, single thread, a few seconds; the same with assertions on and off.
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.lucene.search.suggest.document;
import java.io.File;
import java.net.URI;
import java.util.List;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;
import org.apache.lucene.tests.util.LuceneTestCase;
public class TestContextSuggestFieldJavadocExample extends LuceneTestCase {
// Expected: the class-javadoc example compiles; actual: javac says List<T> does not conform to int.
public void testClassJavadocExampleCompiles() throws Exception {
String source =
"""
import java.util.Arrays;
import org.apache.lucene.document.Document;
import org.apache.lucene.search.suggest.document.ContextSuggestField;
class Example {
void example(Document document, String name) {
document.add(
new ContextSuggestField(name, "suggestion", Arrays.asList("context1", "context2"), 4));
}
}
""";
JavaFileObject unit =
new SimpleJavaFileObject(URI.create("string:///Example.java"), JavaFileObject.Kind.SOURCE) {
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return source;
}
};
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
// Gradle puts Lucene's own dependencies on the module path, so give javac both paths.
String classPath =
System.getProperty("java.class.path")
+ File.pathSeparator
+ System.getProperty("jdk.module.path", "");
List<String> options =
List.of("-classpath", classPath, "-d", createTempDir().toString(), "-proc:none");
boolean compiled =
ToolProvider.getSystemJavaCompiler()
.getTask(null, null, diagnostics, options, null, List.of(unit))
.call();
assertTrue(diagnostics.getDiagnostics().toString(), compiled);
}
}
cp TestContextSuggestFieldJavadocExample.java $LUCENE/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/
cd $LUCENE && ./gradlew :lucene:suggest:test --tests org.apache.lucene.search.suggest.document.TestContextSuggestFieldJavadocExample -Ptests.seed=DEADBEEF
# assertions off: add -Ptests.asserts=false (same result)
- Expected
- The example compiles, and a context1 query for "sugg" returns "suggestion" with score 4, as the corrected call does on main.
- Observed
- javac reports 1 error at the constructor call:
incompatible types: no instance(s) of type variable(s) T exist so that List<T> conforms to int(the test prints it asjava.util.List<T>); the same with assertions off.
More files, environment, full output292 words
- The embedded lines are token-identical to
ContextSuggestField.java:36-37at645d4fe14a20(checked mechanically for the hunt's minimal test). - This file is that minimal test with one change, so it also runs under gradle: javac gets
jdk.module.pathas well asjava.class.path. Under gradlelucene-coresits on the module path, and the verbatim test then also reportspackage org.apache.lucene.document does not existnext to the real error. Run standalone, with every jar on the class path, both versions give the same single error. Example.java:7in the output is the example's constructor line,ContextSuggestField.java:37.- The shortest form needs no test: paste the call into any method with a
Document documentand aString name, importjava.util.Arrays,DocumentandContextSuggestField, and compile; javac reports the same single error, worded... so that List<T> conforms to intplus awhere T is a type-variableline. - As a regression test none is needed for a javadoc-only fix, and this test would not guard the javadoc, because it compiles a copy of the text; and since it fails on purpose, the test framework leaves its temporary directory on disk. The general guard is the tooling #9534 asks for.
| lucene | main 645d4fe14a20 (11.0.0-SNAPSHOT); the same test also fails on the published 10.6.0 and 10.5.2 jars |
|---|---|
| jdk | OpenJDK 25.0.3 (build 25.0.3+9-LTS) |
| os | Linux, aarch64 |
cp TestContextSuggestFieldJavadocExample.java $LUCENE/lucene/suggest/src/test/org/apache/lucene/search/suggest/document/
cd $LUCENE && ./gradlew :lucene:suggest:test --tests org.apache.lucene.search.suggest.document.TestContextSuggestFieldJavadocExample -Ptests.seed=DEADBEEF
# assertions off: add -Ptests.asserts=false (same result)
TestContextSuggestFieldJavadocExample > testClassJavadocExampleCompiles FAILED
java.lang.AssertionError: [/Example.java:7: error: incompatible types: no instance(s) of type variable(s) T exist so that java.util.List<T> conforms to int
new ContextSuggestField(name, "suggestion", Arrays.asList("context1", "context2"), 4));
^, Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output]
at __randomizedtesting.SeedInfo.seed([DEADBEEF:9A7EBD6A0F12FB11]:0)
at junit@4.13.2/org.junit.Assert.fail(Assert.java:89)
at junit@4.13.2/org.junit.Assert.assertTrue(Assert.java:42)
at org.apache.lucene.search.suggest.document.TestContextSuggestFieldJavadocExample.testClassJavadocExampleCompiles(TestContextSuggestFieldJavadocExample.java:63)- It calls a constructor that never existed: (name, value, List, weight). The constructor was (name, Collection, value, weight) in 2015 and is (name, value, weight, contexts...) since 5.3.0.
- Its constructor javadoc, the parent
SuggestFieldexample and all 75 test calls use (name, value, weight, ...). - Varargs was a deliberate change a reviewer asked for; the already-wrong example was not updated.
The full argument202 words
- Contract text.
ContextSuggestField.java:32-33: "Example usage of adding a suggestion with contexts is as follows:", in a block marked<code class="language-java">since #15573 (2026-01-15); nothing calls it pseudo-code.:58-61:@param name,value,weight,contexts. The parent class's example,document.add(new SuggestField(name, "suggestion", 4));(SuggestField.java:42), matchesSuggestField(String name, String value, int weight)(:78). - History. LUCENE-6459 (
be4d58c7740, 2015-05-28, Areek Zillur via Mike McCandless) added the class and the example while the only constructor was(String name, Collection<CharSequence> contexts, String value, int weight): javac against a stub of that signature reportsString cannot be converted to Collection<CharSequence>. In its discussion (#7518) Michael McCandless found that form "somewhat annnoying with Java 7" and asked "Maybe we can improve this to take a varargs?". LUCENE-6515 (cecebbc7506, Areek Zillur, 2015-06-02) made that change and did not touch the example. - Tests. All 75
new ContextSuggestField(calls inlucene/suggest/src/testuse(name, value, weight, contexts...). No test compiles javadoc examples; #9534 (LUCENE-8488, open) asks for that in general. - Precedent. Upstream has fixed wrong javadoc examples before, for example #10088 (LUCENE-9046, "Fix wrong example in Javadoc of TermInSetQuery") and #12693 ("chore: update the Javadoc example in Analyzer").
The devil's-advocate check141 words
Strongest case for "intended" (built by the intended-behaviour checks and the refute review): javadoc code blocks are uncompiled fragments that also leave document and name undeclared; Lucene does not compile-check them (#9534 is open), and in #15225 a maintainer (rmuir) said code examples need to be kept extremely minimal because their maintenance cost is high and they have little validation; the class is @lucene.experimental; and the constructor javadoc just below is right, so a user recovers quickly.
Why it fails: a reader can supply missing declarations, but not a different argument order and type. @lucene.experimental warns that the API may change incompatibly, not that its current docs may be wrong. "Recovers quickly" means low impact, not intended. Every verifier and the adjudication rejected the "intended" reading; it stays at Low because it is a wrong call shape, not a typo.
Recommended A. Write the example's call in constructor order
Put the arguments in constructor order: new ContextSuggestField(name, "suggestion", 4, "context1", "context2"). Javadoc only, one line. Validated: the fixed text compiles, the closest suggest suites pass (21 of 21), and suggest's static checks and javadoc build succeed.
--- a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/ContextSuggestField.java
+++ b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/ContextSuggestField.java
@@ -34,7 +34,7 @@
*
* <pre><code class="language-java">
* document.add(
- * new ContextSuggestField(name, "suggestion", Arrays.asList("context1", "context2"), 4));
+ * new ContextSuggestField(name, "suggestion", 4, "context1", "context2"));
* </code></pre>
*
* Use {@link ContextQuery} to boost and/or filter suggestions at query-time. Use {@linkAll options and trade-offs3 options ยท 483 words
Three ways to resolve it; A is the smallest and was validated. B removes the example instead, which a reviewer may prefer given the "keep code examples minimal" view in #15225; C changes the API to match the doc and is not recommended.
Backport: the diff applies as is on main and branch_11x (same <pre><code class="language-java"> wrapper). On branch_10_6 and the 10.6.0 tag the block still uses <pre class="prettyprint"> (#15573 is not there), so the patch's context lines do not match and the one-line change must be made by hand there (checked with a patch dry run). branch_10x was retired on 2026-10-29 (#16911).
Change ContextSuggestField.java:37 to new ContextSuggestField(name, "suggestion", 4, "context1", "context2"));. Javadoc only, 1 line changed.
--- a/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/ContextSuggestField.java
+++ b/lucene/suggest/src/java/org/apache/lucene/search/suggest/document/ContextSuggestField.java
@@ -34,7 +34,7 @@
*
* <pre><code class="language-java">
* document.add(
- * new ContextSuggestField(name, "suggestion", Arrays.asList("context1", "context2"), 4));
+ * new ContextSuggestField(name, "suggestion", 4, "context1", "context2"));
* </code></pre>
*
* Use {@link ContextQuery} to boost and/or filter suggestions at query-time. Use {@linkTrade-offs
- The smallest change; it shows the varargs form LUCENE-6515 chose.
java.util.Arraysstays used in the class body (:69), so no import changes.- The example no longer shows how to pass an existing
List; a reader who has one needstoArray(new CharSequence[0])(could be a second line if wanted; not run).
What the checks validated
Validated in a scratch worktree of 645d4fe14a20 (removed after the run), through gradle with OpenJDK 25.0.3:
- The patch applies cleanly (1 file, 1 insertion, 1 deletion), and the patched
<pre>block is exactly the text the fixed-text test compiles (2 lines, identical). - Before the patch the repro test fails 1 of 1 with assertions on and off; the fixed-text test (the same test with the call corrected and its comment updated) passes 1 of 1 with assertions on and off.
- The closest suites pass:
TestContextSuggestField(6 tests) andTestContextQuery(15 tests), 21 of 21. :lucene:suggest:check -x test(google-java-format, ecjLint, forbiddenApis; Error Prone is skipped in a default local build) succeeds.:lucene:suggest:renderJavadocsucceeds, and the rendered example readsnew ContextSuggestField(name, "suggestion", 4, "context1", "context2"));.- The hunt's control shows the corrected call working on a real index: a
ContextQueryfor prefix "sugg" oncontext1returns 1 of 2 documents, "suggestion" with score 4, with assertions on and off.
Delete the <pre> block and link the constructor, for example "See {@link #ContextSuggestField(String, String, int, CharSequence...)}".
Trade-offs
- Nothing left to go stale, in line with the "keep code examples minimal" view in #15225.
- The class loses its only code sample. Not run.
Add, for example, ContextSuggestField(String name, String value, Collection<CharSequence> contexts, int weight).
Trade-offs
- An API change to match a doc; it brings back the
Collectionform LUCENE-6515 removed on purpose after the varargs request in #7518. Not run.
No downstream runtime relevance: the broken example cannot compile, so no shipped application can contain it unrepaired.
Non-formal: an AI tool extracted the code examples from the javadocs of Lucene's join, memory, monitor, suggest and facet modules and compiled each against main; this one failed. A one-test repro, a class-file scan of 158 builds for the example's constructor and runs on releases back to 5.3.0 then dated it.
The method in full143 words
- A probe first compiled the block verbatim against the stock main
645d4fe14a20jars and got the error (2026-10-29). - The hunt unit re-ran it, extracted the block mechanically, wrote the one-test repro and checked in which of 158 builds (every cached release from 1.9.1 to 10.5.2, the 10.6.0 RC1 and main) the example's API members exist, with a class-file scan whose boundaries were cross-checked with javac: from 5.3.0 on, the only constructor is
(String, String, int, CharSequence[]). - The history step dated it: 5.2.1 has no such class; a version-neutral port of the text fails from 5.3.0, and its constructor-order control compiles there.
- A corrected-call control on a real index returned the suggestion with weight 4 for
context1, with assertions on and off, so only the text is wrong. - This is a compile check of documentation code, not model checking or a proof.
No matching public report found in GitHub issues, PRs and commits, the JIRA archive, the mailing lists, downstream projects, StackOverflow or the web (searched 2026-10-29 and again 2026-11-01). Nearest: the 2015 issues that added the example and changed the constructor, and #9534, a general wish to compile-check javadoc examples. Not fixed upstream.
Searches3 searches
- Related, not this bug: #7518 (LUCENE-6459, added the class and the example; its comments discuss the API, including the varargs request, never the example); #7573 (LUCENE-6515, changed the constructor; no comment about the example); #7760, #7916 and #9379 (other changes to the class); #9534 (LUCENE-8488, open: compile-check javadoc examples in general); #15225 (open umbrella issue on javadoc quality; names neither the suggest module nor this class); #16824 and #16825 (open outside javadoc reports on other suggest classes); #16936 and #16904 (javadoc fixes in other files). Tracking issue #16937 does not name it.
- Parallel javadoc sweep: the open outside PR #16949 "Fix stale names and examples in javadocs" (27 files) does not touch
ContextSuggestField.java; no open PR does. - Not fixed upstream: the wrong call is still at line 37 on main
f815e679bf6c,branch_11x,branch_10_6andbranch_9_12(2026-11-01).
| Where | When | How | Found |
|---|---|---|---|
| apache/lucene issues, PRs and commits; the JIRA archive; downstream repositories | 2026-11-01 | scripted searches (16 issue/PR, 3 commit, 2 downstream-repo and 4 JIRA-archive queries; 114 distinct hits, 0 high-overlap, 14 medium-overlap; every medium-overlap hit and every hit naming ContextSuggestField read); 32 manual GitHub searches incl. elastic/elasticsearch, opensearch-project/OpenSearch, apache/solr and apache/lucenenet; direct JIRA JQL; the changed files of all 409 open PRs and the 100 most recently updated closed or merged PRs | no report; no open PR touches ContextSuggestField.java |
| Mailing lists, StackOverflow and web | 2026-11-01 | 20 list queries over dev@, java-user@, issues@ and commits@; lists.apache.org for the last 30 days; the StackOverflow API; 6 web queries | no report |
| apache/lucene and the same sources (first search) | 2026-10-29 | scripted searches, 28 manual GitHub searches, the changed files of all 415 open PRs, the verifiers' own searches and a recheck | no report; only the five 2015-2018 issues that name the class |
Added broken by LUCENE-6459 (be4d58c7740, 2015-05-28); LUCENE-6515 (cecebbc7506, 2015-06-02) gave today's error by moving the constructor to varargs. Both first shipped in 5.3.0, so the example never compiled in a release. 5.2.1 has no such class; 5.3.0 to 10.6.0 and main fail.
Versions tested6 rows
- Example:
be4d58c7740(trunk, svn r1682158) /380bb29f395(branch_5x, r1682170), LUCENE-6459 (#7518, "[suggest] Query Interface for suggest API"), 2015-05-28, committed by Michael McCandless; CHANGES.txt for 5.3.0 credits "Areek Zillur via Mike McCandless". It created the file with this example while the constructor was(name, Collection contexts, value, weight).git blameon main still maps lines 36-37 to it. - Constructor:
cecebbc7506/405f4b77337, LUCENE-6515 (#7573, "Suggest API cleanup"), Areek Zillur, 2015-06-02:(String, String, int, CharSequence...); the example was not in the diff. No release had the state between the two commits. - Since: only
378ca8d1bbf3(#15573, 2026-01-15, main) touched the<pre>block, changing its wrapper; the 2021 reformatting2cbf261032d(LUCENE-9570) reflowed the intro sentence above it and left the block unchanged. The two example lines are byte-identical in all 95 release tags of the history clone that contain the file (5.3.0 to 10.6.0). Nine releases are untagged there (8.8.2, 8.9.0 to 8.11.4): the bytecode scan checks the constructor in each; the text was read in the 8.11.4 sources jar and is inferred, not read, for 8.8.2 and 8.9.0 to 8.11.3 (identical in 8.8.1, at the lastbranch_8_8commit of the clone and in 8.11.4).
| Version or commit | Verdict | Result |
|---|---|---|
main 645d4fe14a20 | affected | 1 error with assertions on and off (standalone and gradle); the fixed text compiles with fix A |
10.6.0 (release tag commit 4ae946e5a9b) | affected | 1 error (the JUnit repro on the published jars) |
| 10.5.2 | affected | 1 error with assertions on and off (the JUnit repro) |
| 9.1.0, 9.12.3 | affected | 1 error (the finder's equivalent JUnit test) |
| 5.3.0, 5.5.5, 6.6.6, 7.7.3, 8.11.4, 9.0.0 | affected | does not compile (a version-neutral port of the verbatim text); on 5.3.0 the constructor-order control compiles |
| 5.2.1 | not affected | the class does not exist |
Confirmed by an independent reproducer, reviews by a reviewer from another model family (OpenAI GPT-5.6), an intended-behaviour devil's advocate and an adjudication (high confidence); an audit kept it as a low-priority doc defect. This doc's gradle run validated the fix.
Checks and verdicts254 words
Every check re-ran a repro on main or read the same block; none found a reading under which the example is meant not to compile.
| Check | Verdict | What it found |
|---|---|---|
| cross-model review, refute lens (OpenAI GPT-5.6, executing, 2026-10-29) | real, high confidence | Its own compile test failed and its constructor-order control compiled; the intended argument is weak. |
| independent reproducer | real | Its own test fails on main with assertions on and off, on 10.5.2 and on 9.12.3; its constructor-order control passes on main. |
| cross-model review, intended lens (OpenAI GPT-5.6, read-only) | real, medium confidence | It could not run code; a separate run of the finder's test failed as expected. @lucene.experimental is the strongest defence but does not make an impossible current example correct. |
| intended-behaviour devil's advocate | real, high confidence (documentation defect) | Built the "intended" arguments (fragment, no compile check, experimental, correct constructor javadoc) and rejected each; re-ran the repro on main and 10.5.2. |
| adjudication | confirmed, high confidence, severity Low | Re-ran the independent reproduction's test on main with assertions on and off (both fail) and the independent reproduction's control (passes). |
| audit | confirmed, minor, Low | A real but trivial doc defect. One test; fails with assertions on and off; passes with the fixed line. |
| separate re-run and second refute review (OpenAI GPT-5.6, executing, 2026-11-01) | real, high confidence | The repro fails on main and 10.5.2 with assertions on and off; the constructor-order control passes; the reviewer's own test failed on main and 10.5.2 and its control passed. |
The diagram as a still image, generated with AI and checked against the code. It is under 10 MB, the limit for a GitHub attachment.
- PNG 386 KB
Finding record, Lucene and upstream sources, repro files and diagram notes1,255 words
- Registry title
- ContextSuggestField's class javadoc example calls new ContextSuggestField(name, "suggestion", Arrays.asList("context1", "context2"), 4), but the only constructor is (String name, String value, int weight, CharSequence... contexts), so the example has not compiled on any release since the class was added in 5.3.0 (documentation defect)
- Area
- suggest / document suggesters (ContextSuggestField class javadoc example)
- Priority
- Low, rank 1253: A single broken class javadoc example in the experimental suggest ContextSuggestField fails to compile with no runtime effect while the constructor javadoc is correct.
- Impact class
- minor
- Impact note
- Documentation only, with no runtime effect: a developer who adds context-aware suggestions with the lucene-suggest completion API (ContextSuggestField is @lucene.experimental) and copies the class's only code example gets a compile error on every release since 5.3.0, and javac's message ('List<T> conforms to int') does not point at the argument order; the constructor javadoc a few lines below gives the right order, and no configuration, scale or special input is involved.
- Summary
- The ContextSuggestField javadoc shows how to add a suggestion with two contexts: document.add(new ContextSuggestField(name, "suggestion", Arrays.asList("context1", "context2"), 4)). Copied into code, that line does not compile on any release, because the only constructor takes the weight third and the contexts last, as a varargs list: (name, value, weight, contexts...). Written as new ContextSuggestField(name, "suggestion", 4, "context1", "context2") it compiles, and a ContextQuery on context1 finds the suggestion with weight 4, so only the javadoc is wrong.
- Introduced
- be4d58c7740 (LUCENE-6459, apache/lucene#7518 '[suggest] Query Interface for suggest API'; the patch areek (Areek Zillur) wrote, committed by mikemccand (Michael McCandless), trunk r1682158, author date 2015-05-28; branch_5x 380bb29f395, r1682170): it added ContextSuggestField with this class-javadoc example while the only constructor was (String name, Collection<CharSequence> contexts, String value, int weight), so the example did not compile even then (javac against a signature stub of that constructor: 'String cannot be converted to Collection<CharSequence>'). cecebbc7506 (LUCENE-6515, #7573 'Suggest API cleanup', by areek, 2015-06-02; branch_5x 405f4b77337) then changed the constructor on purpose to (String, String, int, CharSequence...) and left the example unchanged, which gives today's 'List<T> conforms to int' error; neither intermediate state was released. git blame on main 645d4fe14a20 still attributes the example lines to be4d58c7740, and the only later commit to touch the block, 378ca8d1bbf3 (#15573, 2026-01-15), changed only its <pre> wrapper [read: git log, show and blame in the full-history clone; exec: version runs, see affected_versions] (2015-05-28 (be4d58c7740 / 380bb29f395, LUCENE-6459); the constructor change that gives the current error: 2015-06-02 (cecebbc7506 / 405f4b77337, LUCENE-6515))
- First affected version
- 5.3.0 [exec] (the first release with ContextSuggestField; it already has the broken example; 5.2.1 and earlier have no such class [exec])
- Affected versions
- every release from 5.3.0 to 10.5.2 (103 releases), 10.6.0 (RC1 4ae946e5a9b), branch_9_12, branch_10x 657014b3c579, branch_10_6, branch_11x f85446cb1af1 and main 645d4fe14a20; not affected: 5.2.1 and earlier (the class does not exist). Not fixed upstream: all of these branches still have the wrong call at ContextSuggestField.java:37 (2026-10-29; main rechecked the same day). [exec: the finder's test fails on main (-ea and -da), the 10.6.0 RC1, 10.5.2, 9.12.3 and 9.1.0 (the earliest release it can run on); a version-neutral main() port that compiles the same verbatim text fails on 5.3.0, 5.5.5, 6.6.6, 7.7.3, 8.11.4, 9.0.0, 9.12.3, 10.5.2, the 10.6.0 RC1 and main, and its constructor-order control compiles on 5.3.0, 9.12.3, 10.5.2, the 10.6.0 RC1 and main; the independent reproduction's test fails on main (-ea and -da), 10.5.2 and 9.12.3; the intended-behaviour check re-ran the finder's test on 10.5.2] [read: the two example lines are byte-identical in every release tag 5.3.0 to 10.5.2, in the 8.11.4 sources jar and on main; 8.8.2 and 8.9.0 to 8.11.3, untagged in the history clone, were not read: their text is inferred (identical in 8.8.1, at the last branch_8_8 commit of the clone and in 8.11.4); a bytecode scan of every build from 5.3.0 to main finds the single constructor (String, String, int, CharSequence[])]. Caveat: all runs used JDK 25 on Linux aarch64.
- Status
- documented (brief, checks and a per-finding doc exist)
- Verification
- Confirmed by AI-run checks: an independent repro, a cross-model review that agreed, an intended-behaviour check, a prior-report search and a skeptical audit; not yet triaged by a person.
- Found by
- non-formal
- Upstream and prior reports
- none found (searched 2026-10-29; the finder's, the independent reproduction's and the intended-behaviour check's searches agree): scripted searches over GitHub issues, PRs and commits, downstream repositories, the dev@, java-user@, issues@ and commits@ lists, the JIRA archive and the web, 28 manual GitHub searches, StackOverflow, the changed files of all 415 open apache/lucene PRs (none touches ContextSuggestField.java) and of the 60 most recently closed or merged PRs, and the 25 issues and PRs created since 2026-10-27 (nothing on the suggest module). Every apache/lucene item that names ContextSuggestField is one of five closed 2015-2018 issues: #7518 (LUCENE-6459, added the class and the example; its comments discuss the API, including a request for varargs, never the example), #7573 (LUCENE-6515, changed the constructor; no comment about the example), #7760, #7916 and #9379. Read but not the same bug: #11942 and #15573 (later edits of the file), #9534 (LUCENE-8488, an open 2018 wish to compile-check javadoc examples, naming no class), #15225 (open umbrella issue on javadoc quality, no mention of the suggest module), #9020 (LUCENE-7971, a broken SpellChecker javadoc example, another class), #16824 and #16825 (outside suggest-module javadoc reports on other files), #16904 (a javadoc-fix PR for collation/package-info.java, merged 2026-11-02 as e1faeba08bd on main; it does not touch this file). Recheck: four GitHub searches return only the five old issues, the two items updated since a recent cutoff (#16939, #16940) are unrelated, and main 645d4fe14a20 still carries the line. Tracking issue #16937 does not name it.
- Lucene commit tested
- main
645d4fe14a20: the minimal repro with assertions on and off, standalone and through gradle; the recommended fix in a scratch worktree (the fixed text compiled through the same test; the closest suggest suites,:lucene:suggest:check -x testand:lucene:suggest:renderJavadoc). The JUnit repro on the published 10.6.0 and 10.5.2 jars (and, in the hunt, 9.12.3 and 9.1.0); a version-neutral port of the same text on 5.3.0, 5.5.5, 6.6.6, 7.7.3, 8.11.4 and 9.0.0; 5.2.1 has no such class.ContextSuggestField.javais byte-identical on645d4fe14a20and on upstream mainf815e679bf6c(2026-11-01) (read).
- Finding record
lucene/suggest/src/java/org/apache/lucene/search/suggest/document/ContextSuggestField.java:31-46 (the class javadoc, the example at lines 36-37, @lucene.experimental at line 44) and line 65 (the only constructor, ContextSuggestField(String name, String value, int weight, CharSequence... contexts))
- The finding in 30 seconds
lucene/suggest/src/java/org/apache/lucene/search/suggest/document/ContextSuggestField.java (lines 32-38, 55-65)
- Who is affected
lucene/suggest/src/java/org/apache/lucene/search/suggest/document/ContextSuggestField.java (lines 44, 55-65)
- Why it looks unintended
lucene/suggest/src/java/org/apache/lucene/search/suggest/document/ContextSuggestField.java (lines 32-38, 58-61, 65) and SuggestField.java (lines 39-43, 78)lucene/suggest/src/test (75 'new ContextSuggestField(' calls, grep)
- Suggested fix
a Lucene clone origin/branch_11x 603af870375 and origin/branch_10_6 7e5aec4370e (git show of lines 35-38)
- TestContextSuggestFieldJavadocExample.java (JUnit, one test):
repro/LFV-1029/TestContextSuggestFieldJavadocExample.java(65 lines)
Made from the code at 645d4fe14a20, plain javac runs on the verbatim and the corrected lines, the git history and the executed repro, version runs and control (the published example fails with the javac error; the corrected call compiles and is found by a context1 query with score 4). Five steps (what the user does, how javac matches the arguments, expected vs actual, history, the fix) and a summary card, which is also the PNG.
assets/LFV-1029/bug.png(386 KB)
