The completion filter adds romaji tokens to each Japanese word, read row by row from the bundled table romaji_map.txt, so a suggester can match Latin-letter input.
zassi), why zasshi is not a prefix of it, the table rows that miss the doubled spelling, and the executed result. Select the still to open it at full size. Generated with AI, checked against the code.- You index 雑誌 (zasshi), 決して (kesshite), マッチ (macchi) and 三つ (mittsu) as suggestions with
JapaneseCompletionAnalyzer, plus 一緒 (issho) and 抹茶 (maccha), and query withPrefixCompletionQuery. - You expect
zasshito suggest 雑誌, asisshosuggests 一緒: the javadoc lists modified Hepburn, and doubling the consonant is how input methods type a small tsu. - Instead all four return no suggestion, with no error. Of the Latin spellings tried, only the Kunrei ones work (
zassifinds 雑誌,mittufinds 三つ); committed kana work too. - Why: 雑誌 is indexed as
[雑誌, zassi]. Its table rowッシ,ssihas one spelling, whileシ,si,shihas two and the neighbourッショ,ssyo,sshodoublessh. ッチ (tti) and ッツ (ttu) are the same. - Input-method users lose it while composing: ざっs (
zass) finds 雑誌, ざっsh (zassh) finds nothing, the committed ざっし finds it again.
Applications using the opt-in JapaneseCompletionAnalyzer or JapaneseCompletionFilter (also exposed by search servers as kuromoji_completion), with the standard INDEX/QUERY configuration, in every release since 9.0.0. Familiar words, for example 雑誌, 決して, マッチ, 三つ, こっち, 抹茶 (how often such words occur was not measured). People typing raw romaji lose the suggestion; input-method users lose it while composing. Committed kana still match.
Mechanism, terms and numbers580 words
Kuromoji's completion analyzer (JapaneseCompletionAnalyzer, JapaneseCompletionFilter) indexes each Japanese word together with its romaji spellings, so an autocomplete can match Latin-letter input. Its bundled table romaji_map.txt gives the small-tsu rows ッシ, ッチ and ッツ a single Kunrei-style spelling (ssi, tti, ttu), although the base rows list shi, chi, tsu and the neighbouring small-tsu rows double the consonant (ssha, ccha, jji). So 雑誌, 決して, マッチ and 三つ are indexed only as zassi, kessite, matti and mittu, and typing the modified-Hepburn or input-method spellings zasshi, kesshite, macchi or mittsu suggests nothing, with no error. It affects every release from 9.0.0 to 10.6.0 and main; the fix is data only.
- Small tsu (sokuon, ッ / っ): doubles the next consonant. 雑誌 is read ザッシ, za-sshi.
- Romanizations: modified Hepburn writes シ, チ, ツ as
shi,chi,tsuand a small tsu before them assshi,tchi,ttsu(雑誌zasshi, 三つmittsu, 抹茶matcha); Kunrei-shiki writessi,ti,tu(zassi,mittu). Japanese input methods accept both and type a small tsu by doubling the consonant (ss,cc,tt) or withtch;macchiis such an input-method spelling. JapaneseCompletionFilter: for each word it emits the word itself and every romaji spelling of its katakana reading at the same position. The spellings come fromromaji_map.txt, where each row maps a key, mostly a kana unit, to its spellings (for exampleシ,si,shi); the reading is matched longest key first, and every spelling of every matched row is combined (KatakanaRomanizer.java:103-169). The javadoc lists "(modified) Hepburn-shiki, Kunrei-shiki (Nihon-shiki) and Wāpuro shiki" as supported (JapaneseCompletionFilter.java:41-42).- Completion query:
PrefixCompletionQuerymatches a suggestion when the typed text, after the QUERY-mode analyzer, is a prefix of one of the suggestion's indexed forms. Raw romaji such aszasshicomes out as the single tokenzasshi; no romaji token is added.
| row | spellings | base row | neighbouring rows |
|---|---|---|---|
:185 ッシ | ssi | :29 シ,si,shi | :189-191 ッシャ,ssya,ssha / ッシュ,ssyu,sshu / ッショ,ssyo,ssho |
:201 ッチ | tti | :47 チ,ti,chi | :205-207 ッチャ,ttya,ccha,ccya (and ッチュ, ッチョ) |
:202 ッツ | ttu | :48 ツ,tu,tsu | :193 ッジ,zzi,jji, :218 ッフ,hhu,ffu |
Smaller gaps of the same kind: ッチャ, ッチュ, ッチョ have no Hepburn tch form (matcha), and the rare ッヂ, ッヅ, ッヂャ, ッヂュ, ッヂョ rows (:209-210, :213-215) have no zz/jj form.
Index-side tokens on main: 雑誌 → [雑誌, zassi], 決して → [決して, kessite], マッチ → [マッチ, matti], 三つ → [三つ, mittu], こっち → [こっち, kotti]; compare 一緒 → [一緒, issyo, issho] and 抹茶 → [抹茶, mattya, maccha, maccya]. Typed zasshi, kesshite, macchi, matchi, mittsu, matcha: no suggestion, and kocchi is not a prefix of any token of こっち. Typed zassi, kessite, issho, maccha: found. Lucene's Hepburn reading filter (JapaneseReadingFormFilter, useRomaji=true) gives zasshi, kesshite, matchi, mittsu, matcha for the same words.
The code follows the table: romanize() matched a separately coded longest-match model of the same table, bounded-exhaustively, on all 1,830,854 inputs of length up to 3 and on 57,289,761 inputs of length 4 (0 mismatches; a shortest-match mutant was caught). That shows implementation and model agree over the tested domain; the omission itself is in the data rows.
Exposure and likelihood223 words
- Who. Applications that build Japanese autocomplete with
JapaneseCompletionAnalyzerorJapaneseCompletionFilter(also through the analysis SPI asjapaneseCompletion; search servers built on Lucene expose it as akuromoji_completiontoken filter). Opt-in; it reproduces with the standard INDEX/QUERY configuration, no user dictionary and no custom table. - What triggers it. Ordinary words whose reading has ッシ, ッチ or ッツ, typed in modified Hepburn or the way input methods type them: 雑誌
zasshi, 決してkesshite, マッチmacchi/matchi, 三つmittsu, こっちkocchi, and 抹茶matcha(thetchgap). No special input, no scale. - Two groups of users. People who type romaji directly lose the suggestion completely. Input-method users lose it between the small tsu and the completed kana (ざっsh →
zassh, みっts →mitts); handling such mid-composition strings is a stated goal of the feature (JapaneseCompletionFilter.java:184-188). - What still works. Kana committed through an input method (ざっし →
zassi) and the Kunrei spellings (zassi,mittu). - Silent. No exception, no log line: the suggestion list is just shorter.
- After a fix the index-side tokens change, so existing suggest fields must be reindexed. The query side needs no code or configuration change; QUERY mode loads the same table, so kana queries gain the new spellings too (with fix C, ざっし →
[ざっし, zassi, zasshi]).
The test shows that the INDEX-mode JapaneseCompletionAnalyzer gives 雑誌 (ザッシ) only the Kunrei romaji zassi, never the modified-Hepburn zasshi (romaji_map.txt maps ッシ only to ssi), so typing "zasshi" cannot complete it.
/*
* 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.analysis.ja;
import java.util.ArrayList;
import java.util.List;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.tests.util.LuceneTestCase;
public class TestCompletionSokuonHepburn extends LuceneTestCase {
public void testZasshiIsIndexed() throws Exception {
List<String> terms = new ArrayList<>();
try (Analyzer analyzer =
new JapaneseCompletionAnalyzer(null, JapaneseCompletionFilter.Mode.INDEX);
TokenStream ts = analyzer.tokenStream("f", "雑誌")) {
CharTermAttribute term = ts.addAttribute(CharTermAttribute.class);
ts.reset();
while (ts.incrementToken()) {
terms.add(term.toString());
}
ts.end();
}
// expected: the Hepburn spelling "zasshi" among the index-side tokens; actual: [雑誌, zassi]
assertTrue(
"expected zasshi among the index-side tokens, actual: " + terms, terms.contains("zasshi"));
}
}
# in a copy of this finding's repro folder (repro/LFV-849/, which holds src/)
# Lucene checkout at the tested commit, built with: ./gradlew --no-daemon assemble (JDK 25)
LUCENE=/path/to/lucene; V=12.0.0-SNAPSHOT
CP=$LUCENE/lucene/core/build/libs/lucene-core-$V.jar
CP=$CP:$LUCENE/lucene/codecs/build/libs/lucene-codecs-$V.jar
CP=$CP:$LUCENE/lucene/test-framework/build/libs/lucene-test-framework-$V.jar
CP=$CP:$LUCENE/lucene/analysis/common/build/libs/lucene-analysis-common-$V.jar
CP=$CP:$LUCENE/lucene/analysis/kuromoji/build/libs/lucene-analysis-kuromoji-$V.jar
CP=$CP:randomizedtesting-runner-2.9.2.jar:junit-4.13.2.jar:hamcrest-3.0.jar # test-framework dependencies (Maven Central)
CP=$CP:junit-platform-console-standalone-6.1.3.jar # JUnit Platform console launcher (Maven Central)
javac -d classes -cp "$CP" $(find src -name '*.java')
# run 1: assertions on, seed DEADBEEF
java -ea -esa --add-modules jdk.incubator.vector --enable-native-access=ALL-UNNAMED -Dtests.seed=DEADBEEF \
-cp "classes:$CP" org.junit.platform.console.ConsoleLauncher \
execute --select-class org.apache.lucene.analysis.ja.TestCompletionSokuonHepburn
# the module(s) analysis-kuromoji also need their third-party runtime jars
- Expected vs actual
- Expected
zasshiamong the index-side tokens; actual[雑誌, zassi], with-eaand-da.
More files, environment, full output38 words
| lucene | Lucene main e1faeba08bde (2026-11-02) |
|---|---|
| jdk | 25.0.3+9-LTS |
# Lucene main 645d4fe14a20, assertions on (-ea), seed DEADBEEF: 1 test(s) run, 1 failed
=> java.lang.AssertionError: expected zasshi among the index-side tokens, actual: [雑誌, zassi]
org.junit.Assert.fail(Assert.java:89)
org.junit.Assert.assertTrue(Assert.java:42)
org.apache.lucene.analysis.ja.TestCompletionSokuonHepburn.testZasshiIsIndexed(TestCompletionSokuonHepburn.java:41)- The javadoc lists "(modified) Hepburn-shiki" as supported;
zasshi,mittsuandmatchaare Hepburn, and Lucene's own Hepburn reading filter emits them. - The same table doubles
sh,ch,jandfon the neighbouring small-tsu rows (ッショ,ssyo,ssho,ッチャ,ttya,ccha,ccya,ッジ,zzi,jji). - In the introducing PR's review, the same kind of gap (no
jjion ッジ) was fixed on request: "yes, of course".
The full argument349 words
- The contract names modified Hepburn.
JapaneseCompletionFilter.java:41-42andromaji_map.txt:3list "(modified) Hepburn-shiki" as supported.zasshi,kesshite,mittsuandmatchaare the modified-Hepburn forms, andJapaneseReadingFormFilterwithuseRomaji=trueemits them. - The feature exists to cover more than Hepburn. The introducing issue #11140 says
JapaneseReadingFormFilter"supports only modified Hepburn-shiki, so it isn't sufficient to cover all possible romanized forms". For these words the completion filter covers fewer forms than that filter. - The disclaimer's example does not explain it.
JapaneseCompletionFilter.java:44-48: "This does not strictly comply with the romanization systems listed above, but tries to cover possible keystroke supported by various Input Methods. e.g.: Circumflex / Macron representing Chōonpu (長音符) are not supported." Doubled consonants (ss,cc,tt) andtchare ordinary input-method keystrokes for a small tsu (the open-source Mozc input method maps each to っ), so the disclaimer's stated aim argues for them. Its example ("e.g.") of what is not supported is long-vowel marks; no comment, test or doc names the small-tsu rows. The first wording, replaced a day later by5dfbef313cf(before 9.0.0), excluded "romanji forms which are official but not commonly used with Japanese Input Methods". - The neighbouring rows follow the rule. The table doubles
sh,ch,jandfon the neighbouring small-tsu rows (:189-191,:193,:205-207,:218); the base rows シ, チ, ツ list two spellings each. (It is not consistent everywhere: a sibling bug covers two copy errors on other small-tsu rows,:281 ッスォand:289 ッドゥ.) - The same gap was fixed on request. In the review of PR #297, a reviewer (GitHub johtani) asked on the
ッジ,zzirow "Should we add jji? I usually use jajji for ジャッジ"; the author (GitHub mocobeta) answered "yes, of course" and addedjji,jja,jju,jjo(PR commitfc90e452474), whose diff showsッチ,ttiandッツ,ttuas unchanged context. - Nothing pins the current spellings. No upstream test covers a small tsu before シ, チ or ツ (they cover サッカ, ヒャッカテン, コダッk and サッk), and no comment, CHANGES or MIGRATE entry mentions it.
The devil's-advocate check130 words
The strongest case (the cross-model review and the intended-behaviour checker): the table is a curated, best-effort set ("does not strictly comply"), every extra spelling multiplies the completion paths (the expansion behind a separate registry bug), and the document-suggester classes are @lucene.experimental.
Why it fails: the table gives two to four spellings to 123 of its 329 rows and to 56 of the 158 rows whose key starts with ッ (ッファ, ッフィ, ッフェ, ッフォ list four), so bounding the product cannot explain dropping exactly these rows; the review that added jji treated the same gap as an omission; and the defect is in the tokens of the kuromoji filter, which is not marked experimental and feeds any suggester. What remains is a labelling question (bug fix or improvement), not intent.
Recommended The doubled spellings on all 11 small-tsu rows that lack them (broadest)
The broadest of three data-only options: add the doubled spellings to romaji_map.txt: ッシ,ssi,sshi, ッチ,tti,cchi,tchi, ッツ,ttu,ttsu, plus tch on ッチャ/ッチュ/ッチョ and zz/jj on the ッヂ/ッヅ rows (11 rows). The repro passes and all 196 kuromoji tests pass, assertions on and off. Existing suggest fields need reindexing.
-ッシ,ssi
+ッシ,ssi,sshi
-ッチ,tti
-ッツ,ttu
+ッチ,tti,cchi,tchi
+ッツ,ttu,ttsu
-ッチャ,ttya,ccha,ccya
+ッチャ,ttya,ccha,ccya,tcha
(ッチュ, ッチョ: + tchu, tcho)
-ッヂ,ddi,
-ッヅ,ddu
+ッヂ,ddi,zzi,jji
+ッヅ,ddu,zzu
(ッヂャ, ッヂュ, ッヂョ: + zzya,jja / zzyu,jju / zzyo,jjo)All options and trade-offs3 options · 598 words
All options are edits of the bundled table only; no Java changes. Fix C and fix A were validated in a scratch worktree at a9779ef3c193 with the whole :lucene:analysis:kuromoji:test task plus the paste-ready test; fix A also with assertions off in the independent fact check; fix B was validated by the independent reproducer with the standalone runner. A fixes the four headline misses, B adds the Hepburn tch forms, C also adds the rare ッヂ/ッヅ rows for consistency, which are the least supported part. None touches the separate copy-error rows :281 ッスォ and :289 ッドゥ.
The doubled spellings on all 11 small-tsu rows that lack them (broadest) (validated by the checks) (recommended)
Each affected row gets its base row's spellings with the first consonant doubled (sh → ssh, ch → cch, ts → tts, z/j → zz/jj), plus the Hepburn tch form on ッチ, ッチャ, ッチュ and ッチョ.
-ッシ,ssi
+ッシ,ssi,sshi
-ッチ,tti
-ッツ,ttu
+ッチ,tti,cchi,tchi
+ッツ,ttu,ttsu
-ッチャ,ttya,ccha,ccya
+ッチャ,ttya,ccha,ccya,tcha
(ッチュ, ッチョ: + tchu, tcho)
-ッヂ,ddi,
-ッヅ,ddu
+ッヂ,ddi,zzi,jji
+ッヅ,ddu,zzu
(ッヂャ, ッヂュ, ッヂョ: + zzya,jja / zzyu,jju / zzyo,jjo)Trade-offs
- Every extra spelling multiplies a word's romaji tokens: each ッシ, ッツ or ッヅ in a reading doubles the count, each ッチ, ッヂ, ッヂャ, ッヂュ or ッヂョ triples it, and ッチャ/ッチュ/ッチョ go from 3 to 4 spellings. マッチ goes from
[matti]to[matti, macchi, matchi]. That slightly enlarges a separate unbounded-expansion issue (different fix site); the module's random and huge-string tests still pass. - The ッヂ/ッヅ part (5 rows) concerns rare kana and is not directly asserted by any test run. For it: the table's own closure check flags these rows, and the finder's standards check finds their Hepburn and Kunrei images missing. Against it: in the saved input-method table the new
zzi/jjicompose to っじ (not っぢ),zzuto っず (not っづ), and the yōon forms likewise to ジ forms, although the base rows already alias ヂ with ジ and ヅ with ズ. Keep it for consistency, not as a headline, or drop it (the 6-row option). - Existing suggest fields must be reindexed to gain the new tokens. The query side needs no code or configuration change (kana queries gain the new spellings too).
What the checks validated
- Scratch worktree at
a9779ef3c193, gradle, seed DEADBEEF: the paste-ready test fails on stock main with assertions on and off; with this fix the whole:lucene:analysis:kuromoji:testtask passes, 31 classes, 196 tests, 0 failures (7 skipped, all in pre-existing module tests: TestExtendedMode 1, TestFactories 1, TestJapaneseNumberFilter 2, TestJapaneseTokenizer 3; no stock whole-module run to compare), with assertions on and off. - With the paste-ready test,
ecjLintTestandcheckGoogleJavaFormatpass. - The repro runner with the fixed table first on the class path: the paste-ready test and the end-to-end suggester test pass; earlier, the 13 upstream completion tests passed with the combined table of all four sibling table fixes under 4 seeds, all with assertions on.
ッシ,ssi,sshi, ッチ,tti,cchi,tchi, ッツ,ttu,ttsu (+3/-3).
Trade-offs
Smallest change; leaves matcha and the ッヂ/ッヅ rows as they are.
What the checks validated
The whole kuromoji test task: 31 classes, 196 tests, 0 failures, with assertions on (this doc) and off (the independent fact check); the end-to-end test passes too.
Adds matcha-style Hepburn spellings, without the rare ッヂ/ッヅ rows.
Trade-offs
Middle ground between the two options above.
What the checks validated
By the independent reproducer only, with the standalone runner: its 4 tests pass with this table.
Search servers that expose this filter as kuromoji_completion load the same table from the Lucene jar, so their Japanese autocomplete should miss the same spellings (inferred from the code; not run on those servers).
Semi-formal. A self-consistency check of the table (every ッK row should list K's spellings with the first consonant doubled) and a Hepburn standards check flagged these rows; a bounded-exhaustive check showed KatakanaRomanizer implements the table as written (0 mismatches on 59 million inputs). A public-API JUnit then reproduced the missing suggestions.
The method in full219 words
- First signal. A planning probe checked
romaji_map.txtagainst its own small-tsu rule and flagged ッシ, ッチ, ッツ and the ッヂ/ッヅ rows; its end-to-end probe showedzasshi,kesshite,macchiandmittsureturning no suggestion on the stock main jars. - Table laws. A model of the table's rules: the gemination-closure law found 10 violations, 8 of them this bug's rows (the other 2 belong to a sibling copy-error bug).
- Translation validation (bounded-exhaustive). Part A:
romanize()equals an independent longest-match model of the table on all 1,830,854 inputs of length up to 3 and 57,289,761 inputs of length 4 (0 mismatches; a shortest-match mutant: 33,518 mismatches); the Part A counters completed, then that process ran out of memory entering Part B, so Parts B and C ran separately. Part B: the modified-Hepburn, Kunrei and Nihon-shiki images of every sequence of up to 4 kana units, from an independent standards table, isolate the failing small-tsu units. Part C: typing the words through a model input method (the open-source Mozc romaji table) finds the failing composition statesっsh,っtsandtc. - Reduction. A public-API JUnit with the document suggester on the stock main jars (2026-10-28), then this doc's kuromoji-only test.
- Tier. Semi-formal: the first signal came from a table self-consistency script, not from a solver's or model checker's own output.
No matching prior report found in the sources searched (as of 2026-10-28) in GitHub issues, PRs and commits, JIRA, the mailing lists, open and recent PRs' changed files, downstream projects and the web. Closest: the introducing PR #297, whose review added a missing jji on ッジ.
Searches4 searches
No report of this defect was found. The closest upstream text is the PR #297 review exchange about jji, a precedent for treating such gaps as omissions, not a report of these rows. The table's data rows have not changed since 9.0.0 and no open PR touches the file.
| Where | When | How | Found |
|---|---|---|---|
| GitHub issues, PRs and commits (apache/lucene), downstream repositories, mailing lists (dev@, java-user@, issues@, commits@), JIRA archive, web | 2026-10-28 | the scripted prior-report search, 51 queries, plus a 28-query lists and JIRA variant (24 list and 4 JIRA queries, 283 hits, triaged) | run 1: no high hit, 7 medium (#11140, #297, #16416 and web documentation pages); the variant: one high hit, LUCENE-10102 (#11140, the introduction), the rest low; nothing about these rows |
| GitHub, by hand (apache/lucene, downstream projects and all of GitHub) | 2026-10-28 | 16 queries on apache/lucene (romaji, Hepburn, kuromoji completion, sokuon, ッシ, 促音, ローマ字, gemination, kunrei, wapuro, ...) and 12 downstream and global queries (JapaneseCompletionFilter, KatakanaRomanizer, romaji_map.txt) | #11140, #297, #12047 (header typos), #11399 (offsets), #16416 (refactor), #12044, #12885 (a different class); downstream documentation and exposure items only |
| Open and recent PRs | 2026-10-28 | the changed files of all 411 open apache/lucene PRs and of the 150 PRs closed 2026-09-04 to 2026-10-28; PRs updated since 2026-10-26 | none touches romaji_map.txt, KatakanaRomanizer or JapaneseCompletionFilter (#16911 deletes all of branch_10x; not a fix) |
| Web (English and Japanese) | 2026-10-28 | romaji_map.txt, zasshi, sshi/ttsu, sokuon, 促音 サジェスト, ヘボン式 っし | vendor documentation and how-to posts; none mentions these rows. The author's 2020 public version of the table has the same rows, undiscussed |
In the table since it was added with the feature (4e86df96c03, #297, 2021-09-17; first released in 9.0.0); its data rows never changed. Fails on all 33 releases from 9.0.0 to 10.5.2, on 10.6.0 (branch_10_6 4ae946e5a9b) and on main.
Versions tested6 rows
Introduced with the feature: 4e86df96c03 "LUCENE-10102: Add JapaneseCompletionFilter for Input Method-aware auto-completion (#297)", 2021-09-17 (issue #11140), which created romaji_map.txt; git blame on main assigns every affected row to it. The PR's first commit dff3942eed5 (2021-09-13) already had ッシ,ssi, ッチ,tti, ッツ,ttu; the review commit fc90e452474 added jji to the ッジ rows and left ッシ, ッチ and ッツ unchanged. The only later commit to the file, 4676a735c18 (#12047, 2023-01-02), fixed header comments.
Executed: all 33 releases from 9.0.0 to 10.5.2 (21 in 9.x, 12 in 10.x) and the branch_10_6 head 4ae946e5a9b (assertions on), and main (on and off), fail the same way; a fixed table on the classpath turns 9.0.0 and 10.5.2 into passes. 8.11.x has no completion filter. Upstream main 20ced71c1e6 and branch_10x carry the same table (read only). No fix upstream.
| Version or commit | Verdict | Result |
|---|---|---|
main a9779ef3c193 | affected | paste-ready test fails (gradle and runner, assertions on and off); the end-to-end and reproducer tests fail |
| 10.5.2, 9.12.3 | affected | paste-ready test fails with the same message (published jars, assertions on) |
9.0.0 to 10.5.2 (33 releases), branch_10_6 4ae946e5a9b | affected | end-to-end suggester test, assertions on: the same four missing suggestions in every release |
| 8.11.0, 8.11.4 | no API | no completion filter: the test fails to compile only on JapaneseCompletionAnalyzer / JapaneseCompletionFilter |
| 9.0.0, 10.5.2 + fixed table | not affected | the end-to-end test passes |
| main + fix C, main + fix A | not affected | the paste-ready test passes; the whole kuromoji test task passes (196 tests) |
The finder, an independent reproducer, an intended-behaviour checker, the adjudication and a credibility audit all ran code and said real. A reviewer from another model family (OpenAI GPT-5.6) could not run code; on reading it agreed with the root cause. This doc's gradle runs confirm the repro and both validated fixes.
Checks and verdicts369 words
Every verdict except the cross-model review's rests on executed runs on main a9779ef3c193. The cross-model review read the checkout at ea57360912ed, where the table is identical.
| Check | Verdict | What it found |
|---|---|---|
| finder | candidate | Table-law model (10 gemination-closure violations), bounded-exhaustive check of the real romanizer (Parts A-C); the end-to-end JUnit fails on main with assertions on and off, 10.5.2 and 9.0.0; the fixed table passes. |
| independent reproducer | real | Own public-API test: 3 of 4 fail on main (assertions on and off), 10.5.2 (on and off) and 9.12.3; the Hepburn reading-filter control passes; its own table fix passes 4 of 4. Found the PR #297 jji review exchange. |
| intended-behaviour checker | real, high | Rejected the best-effort disclaimer, the 'query mode targets input methods only' reading and the 'bound the romaji product' reading; re-ran the test on main and 10.5.2: fails. Probed the composition states. |
| refute review (OpenAI GPT-5.6) | not real, low (procedural) | Could not run any command in four attempts, so it voted not real on procedure only; on reading it agrees with the root cause and writes that static review "strongly favors a genuine resource-table defect". It read Lucene head ea57360912ed, where the table and the completion classes are identical. A separate run re-ran the finder's test on 10.5.2 with assertions off: fails. |
| adjudication | confirmed, high; silent wrong results | Re-ran the reproducer's test on main with assertions on and off: 3 of 4 fail with the same messages. |
| credibility audit | keep | Re-ran the finder's test on main with assertions on and off: fails, controls pass; re-read the table rows and re-checked prior art. |
| this doc | reproduces; fixes validated | Gradle in a scratch worktree: the paste-ready test fails on stock main with assertions on and off; fix C (on and off) and fix A (on) pass the whole kuromoji test task, 196 tests. |
| fact checks of this doc | holds after corrections | An independent fact check re-ran the gradle repro (assertions on and off), fix A (off) and fix C (on and off), and a real-suggester probe; a reviewer from another model family (OpenAI GPT-5.6) re-checked the claims against the saved evidence. Their corrections are applied. |
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 516 KB
Finding record, Lucene and upstream sources, repro files and diagram notes1,251 words
- Registry title
- Japanese completion suggester (JapaneseCompletionAnalyzer / JapaneseCompletionFilter): words with a small tsu before shi, chi or tsu (雑誌, 決して, マッチ, 三つ) are never suggested for their Hepburn or input-method spellings zasshi, kesshite, macchi/matchi, mittsu, because romaji_map.txt maps ッシ only to 'ssi', ッチ only to 'tti' and ッツ only to 'ttu', while the base rows シ/チ/ツ list shi/chi/tsu and the neighbouring rows ッシャ and ッチャ do double the consonant ('ssha', 'ccha')
- Area
- analysis / kuromoji completion romanization (romaji_map.txt read by KatakanaRomanizer; JapaneseCompletionFilter, JapaneseCompletionAnalyzer)
- Priority
- Medium, rank 147: Common words such as 雑誌, 決して, マッチ and 三つ silently get no suggestion in the opt-in kuromoji completion analyzer for their usual Hepburn spellings, and that broad trigger on everyday words puts it in Medium at the end of the opt-in silent analysis rows, while its sibling completion-table rows LFV-850, LFV-848 and LFV-854 stay Low.
- Impact class
- silent wrong results
- Impact note
- Applications that build Japanese autocomplete with JapaneseCompletionAnalyzer or JapaneseCompletionFilter (an opt-in kuromoji analyzer, used with its default settings; downstream search servers expose it as a kuromoji_completion filter), in every release from 9.0.0 to 10.6.0 and main: every word whose reading contains ッシ, ッチ or ッツ (雑誌, 決して, 必死, こっち, 一致, 三つ, 四つ) is indexed only with the Kunrei-style romaji (zassi, kessite, matti, mittu), so a query typed in raw romaji with the Hepburn or doubled-consonant spelling (zasshi, kesshite, macchi, matchi, mittsu, and matcha for 抹茶) gets no suggestion; kana committed through an input method still match, and input-method users lose the suggestion only while composing (ざっsh, みっts); no scale is needed and there is no error; a fix changes the index-side romaji tokens, so existing suggest fields would need reindexing to benefit.
- Summary
- You index 雑誌 ('magazine'), マッチ ('match') and 三つ ('three') in a document suggester with JapaneseCompletionAnalyzer, whose javadoc lists modified Hepburn among the supported romanizations, and expect typing 'zasshi', 'macchi' or 'mittsu' to suggest them, just as 'issho' suggests 一緒 and 'maccha' suggests 抹茶. Instead nothing is suggested: the bundled romaji_map.txt gives the small-tsu rows ッシ, ッチ and ッツ only the spellings 'ssi', 'tti' and 'ttu', although the base rows シ, チ, ツ list shi, chi, tsu and the neighbouring rows ッシャ and ッチャ list 'ssha' and 'ccha'. Only the Kunrei spellings (zassi, matti, mittu) find these words.
- Introduced
- 4e86df96c0385a7b552434d7e2a9bee69f18bd77 (LUCENE-10102 / issue #11140, PR #297, 'Add JapaneseCompletionFilter for Input Method-aware auto-completion'): the commit created romaji_map.txt with the defective rows [read: git log --follow and git blame of romaji_map.txt on main]. Inside the PR, its first commit dff3942eed5 (2021-09-13) already had ッシ,ssi / ッチ,tti / ッツ,ttu, and PR commit fc90e452474 (2021-09-17) added jji/jja/jju/jjo to the ッジ rows after a review request while leaving these rows unchanged [read]. The only later commit to the file, 4676a735c18 (#12047, 2023-01-02), changed header comments only. (2021-09-17 (author and merge date of 4e86df96c03))
- First affected version
- 9.0.0 [exec] (the first release with JapaneseCompletionFilter / romaji_map.txt; on 8.11.0 and 8.11.4 the repro fails to compile only because those classes are absent)
- Affected versions
- Every release from 9.0.0 to 10.5.2 (33 releases; latest 9.x: 9.12.3; latest 10.x before 10.6.0: 10.5.2), the branch_10_6 head 4ae946e5a9b9 (10.6.0, released 2026-10-29) and main a9779ef3c193 [exec: the same JUnit fails identically on each with -ea, main also with -da; a fixed romaji_map.txt on the classpath turns it into a pass on 9.0.0 and 10.5.2]. Upstream main 20ced71c1e6 and branch_10x carry the identical table blob [read]. The release jars ship two blobs of the file (4a803a469ad in 9.x, 8136668e708 in 10.x and main) with identical data rows [read]. No fix exists; no regression window and no last good version.
- Status
- documented (brief, checks and a per-finding doc exist)
- Verification
- Confirmed by AI-run checks: an independent repro, a cross-model review that could only read the code (its low-confidence “not real” is procedural), an intended-behaviour check, a prior-report search and a skeptical audit; not yet triaged by a person.
- Found by
- semi-formal; also reached by exhaustive check
- Upstream and prior reports
- none found (2026-10-28, read-only; the prior-report record, verdict new: a scripted prior-report search with 51 queries over apache/lucene issues, PRs and commits, downstream repositories, the dev@, java-user@, issues@ and commits@ lists, the JIRA archive and the web, a 283-hit lists and JIRA variant, manual GitHub searches, the changed files of 411 open PRs and of the PRs closed since 2026-09-04, and the review threads of #297, #11140 and #12047; a later re-check: no apache/lucene PR or issue updated since 2026-10-26 concerns kuromoji or romaji, and no open PR #16805-#16926 touches kuromoji files; its keyword searches hit the search rate limit and rest on the earlier runs): no issue, PR, JIRA entry, list thread or downstream report says that ッシ, ッチ or ッツ lack the sshi, cchi/tchi or ttsu spellings, or that zasshi or mittsu get no suggestion. Related, different: #11140 / #297 (the introduction; in #297's review a reviewer, GitHub johtani, asked to add jji to ッジ and the author agreed: a precedent, not a report of these rows), #12047 (header typos), #11399 (JapaneseCompletionFilter offsets, open), #16416 (ArrayDeque refactor of the filter), #12885 (JapaneseReadingFormFilter OOV hiragana), #16911 (decommissions branch_10x, which removes the file there; not a fix), elastic/elasticsearch#117807 and opensearch-project/OpenSearch#4835 (downstream docs and exposure only).
- Lucene commit tested
- main
a9779ef3c193(gradle in a scratch worktree, assertions on and off, and the standalone JUnit runner); the release jars 10.5.2 and 9.12.3 (this doc's paste-ready test); all 33 releases from 9.0.0 to 10.5.2 and the branch_10_6 head4ae946e5a9b(the history step, end-to-end suggester test); fix A and fix C tables on main (gradle, whole kuromoji test task).
- Finding record
lucene/analysis/kuromoji/src/resources/org/apache/lucene/analysis/ja/completion/romaji_map.txt:3-5 (at a9779ef3c193) (header: 'covers romanization systems: modified Hepburn-shiki, Kunrei-shiki (Nihon-shiki), and Wāpuro shiki'; 'does not strictly comply ... but tries to cover possible keystroke supported by various Input Methods')lucene/analysis/kuromoji/src/resources/org/apache/lucene/analysis/ja/completion/romaji_map.txt:29 (at a9779ef3c193) (シ,si,shi), :47 (チ,ti,chi), :48 (ツ,tu,tsu)lucene/analysis/kuromoji/src/resources/org/apache/lucene/analysis/ja/completion/romaji_map.txt:185 (at a9779ef3c193) (ッシ,ssi), :189-191 (ッシャ,ssya,ssha / ッシュ,ssyu,sshu / ッショ,ssyo,ssho), :193 (ッジ,zzi,jji), :201 (ッチ,tti), :202 (ッツ,ttu), :205-207 (ッチャ,ttya,ccha,ccya ... no tch), :209-215 (ッヂ,ddi, / ッヅ,ddu / ッヂャ,ddya ...), :218 (ッフ,hhu,ffu)lucene/analysis/kuromoji/src/java/org/apache/lucene/analysis/ja/JapaneseCompletionFilter.java:41-42 (at a9779ef3c193) ('Supported romanization systems: (modified) Hepburn-shiki, Kunrei-shiki (Nihon-shiki) and Wāpuro shiki'), :44-48 (disclaimer naming only circumflex/macron long vowels as unsupported), :217-233 (generateOutputs: index-side tokens are the surface form plus KatakanaRomanizer.romanize of the reading)lucene/analysis/kuromoji/src/java/org/apache/lucene/analysis/ja/completion/KatakanaRomanizer.java:103-169 (at a9779ef3c193) (romanize: greedy longest match over the table rows, Cartesian product of the matched row's spellings)
- The finding in 30 seconds
lucene/analysis/kuromoji/src/resources/org/apache/lucene/analysis/ja/completion/romaji_map.txt:3-5 (at a9779ef3c193) (header), :29, :47, :48, :185, :189-191, :193, :201, :202, :205-207, :209-210, :213-215, :218lucene/analysis/kuromoji/src/java/org/apache/lucene/analysis/ja/JapaneseCompletionFilter.java:41-48 (at a9779ef3c193) (javadoc), :180-193 (mid-composition), :217-233 (generateOutputs)lucene/analysis/kuromoji/src/java/org/apache/lucene/analysis/ja/completion/KatakanaRomanizer.java:52-65 (at a9779ef3c193) (table load), :103-169 (romanize)
- Who is affected
lucene/analysis/kuromoji/src/java/org/apache/lucene/analysis/ja/JapaneseCompletionAnalyzer.java:42-59 (at a9779ef3c193) (INDEX/QUERY constructor, analysis chain)lucene/analysis/kuromoji/src/java/org/apache/lucene/analysis/ja/JapaneseCompletionFilter.java:184-188 (at a9779ef3c193) (mid-IME composition comment)
- Why it looks unintended
lucene/analysis/kuromoji/src/java/org/apache/lucene/analysis/ja/JapaneseCompletionFilter.java:41-48 (at a9779ef3c193)lucene/analysis/kuromoji/src/resources/org/apache/lucene/analysis/ja/completion/romaji_map.txt:3-5, (at a9779ef3c193) :29, :47, :48, :189-191, :193, :205-207, :218lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/TestJapaneseCompletionFilter.java:215-216; (at a9779ef3c193) completion/TestKatakanaRomanizer.java:39-52lucene/suggest/src/java/org/apache/lucene/search/suggest/document/CompletionAnalyzer.java:35, (at a9779ef3c193) SuggestField.java:48, PrefixCompletionQuery.java:39 (@lucene.experimental)row counts: a parse of romaji_map.txt at a9779ef3c193 with the loader's rules (329 rows, 123 with 2-4 spellings; 158 rows whose key starts with ッ (157 without the bare row ッ,xtu), 56 with 2-4)
- Suggested fix
lucene/analysis/kuromoji/src/java/org/apache/lucene/analysis/ja/completion/KatakanaRomanizer.java:138-156 (at a9779ef3c193) (Cartesian product)
- TestCompletionSokuonHepburn.java (JUnit test):
repro/LFV-849/src/org/apache/lucene/analysis/ja/TestCompletionSokuonHepburn.java(44 lines)
The PNG is the summary card. Made in parallel with this doc.
assets/LFV-849/bug.png(516 KB)
![Summary card of the bug. Panel 1: the application indexes 雑誌 with JapaneseCompletionAnalyzer and queries 'zasshi' with PrefixCompletionQuery, expecting [雑誌]; the javadoc lists modified Hepburn as supported. Panel 2: 雑誌 has the reading ザッシ, split by longest match into ザ za and ッシ ssi, so the index-side tokens are 雑誌 and zassi; typed 'zasshi' and indexed 'zassi' differ at the 5th letter, so the suggester returns nothing. Panel 3: romaji_map.txt doubles the consonant on its neighbouring small-tsu rows but has only ssi, tti and ttu for ッシ, ッチ and ッツ. Panel 4: zasshi, kesshite, macchi, mittsu, matcha and the composition ざっsh find nothing on main; the Kunrei spellings, issho, maccha and committed kana still match; the data-only fix makes all of them found.](../assets/LFV-849/bug.png)