infinilabs/analysis-ik · error · IllegalArgumentException

length < 0

Error message

length < 0

What it means

The Lexeme constructor (a 'lexeme' is one token produced by the IK segmenter: begin offset + length + type) rejects any token whose character length is negative. A negative length is structurally impossible for a valid token, so this IllegalArgumentException signals that the caller computed begin/end offsets inconsistently. It is an argument-contract guard inside the public constructor org.wltea.analyzer.core.Lexeme#Lexeme(int,int,int,int).

Source

Thrown at core/src/main/java/org/wltea/analyzer/core/Lexeme.java:69

	public static final int TYPE_CQUAN = 48;
	
	//词元的起始位移
	private int offset;
    //词元的相对起始位置
    private int begin;
    //词元的长度
    private int length;
    //词元文本
    private String lexemeText;
    //词元类型
    private int lexemeType;
    
    
	public Lexeme(int offset , int begin , int length , int lexemeType){
		this.offset = offset;
		this.begin = begin;
		if(length < 0){
			throw new IllegalArgumentException("length < 0");
		}
		this.length = length;
		this.lexemeType = lexemeType;
	}
	
    /*
     * 判断词元相等算法
     * 起始位置偏移、起始位置、终止位置相同
     * @see java.lang.Object#equals(Object o)
     */
	public boolean equals(Object o){
		if(o == null){
			return false;
		}
		
		if(this == o){
			return true;
		}

View on GitHub (pinned to 6d2d70fd1a)

Solutions

  1. If you construct Lexeme yourself, compute length as Math.max(0, end - begin) or assert end >= begin before calling the constructor
  2. Audit the two inputs that produce length: in library-internal paths the exception means the AnalyzeContext cursor/offset bookkeeping got corrupted — capture the input text and the segmenter that was active (useSmart on/off) and reduce to a minimal repro
  3. If reproducible against the stock segmenters with normal Chinese text, file an upstream issue with the failing input string — stock paths should never produce negative lengths
  4. Never wrap the call in a silent catch that substitutes length=0; that masks offset corruption and produces wrong term positions downstream

Example fix

// before
int end = computeEnd();
Lexeme l = new Lexeme(offset, begin, end - begin, Lexeme.TYPE_CJK_NORMAL); // throws when end < begin

// after
int end = computeEnd();
if (end < begin) throw new IllegalStateException("corrupted offsets: begin=" + begin + ", end=" + end);
Lexeme l = new Lexeme(offset, begin, end - begin, Lexeme.TYPE_CJK_NORMAL);
Defensive patterns

Strategy: validation

Validate before calling

if (end - begin < 0) {
    throw new IllegalStateException("invalid lexeme bounds: begin=" + begin + ", end=" + end);
}
Lexeme lexeme = new Lexeme(offset, begin, end - begin, Lexeme.TYPE_CJK_NORMAL);

Type guard

private static boolean isValidLexemeLength(int begin, int end) {
    return end >= begin; // length = end - begin must be >= 0
}

Try / catch

try {
    Lexeme lexeme = new Lexeme(offset, begin, length, type);
} catch (IllegalArgumentException e) {
    if (!"length < 0".equals(e.getMessage())) throw e;
    throw new IllegalStateException("segmenter produced inverted bounds at offset " + offset, e);
}

Prevention

When it happens

Trigger: Calling new Lexeme(offset, begin, length, lexemeType) with a negative length argument. Inside the library this happens when a segmenter or LexemePath merge computes length as (end - begin) while end < begin — e.g. overlapping lexemes merged in the wrong order, or a custom segmenter appending Lexeme objects with hand-computed offsets. User code that builds Lexeme instances directly (custom similarity/LexemePath experiments) and passes begin > end arithmetic hits it immediately.

Common situations: Writing a custom Segmenter plugin that emits Lexemes with begin beyond the current cursor; porting code from an IK version where length was unchecked; unit tests that construct Lexemes with placeholder offsets like (0, 5, -1, 0); downstream code that derives length from two independently computed positions that drift apart when the char buffer is refilled.

Related errors


AI-assisted analysis of infinilabs/analysis-ik@6d2d70fd1a (2026-08-14). Data as JSON: /api/errors/dafe021b2026f021. Report an issue: GitHub.