elastic/elasticsearch · error · IllegalArgumentException
CompilationUnit has no lexical information for output
Error message
CompilationUnit has no lexical information for output
What it means
Thrown by AbstractVersionsTask.writeOutNewContents when the JavaParser CompilationUnit does not carry the LexicalPreservingPrinter.NODE_TEXT_DATA, meaning LexicalPreservingPrinter.setup() was never called on the parsed source. Without lexical info, LexicalPreservingPrinter.print cannot reproduce the original formatting, so the task refuses to write to avoid corrupting the source file.
Source
Thrown at build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/AbstractVersionsTask.java:159
static OptionalInt findSingleIntegerExpr(FieldDeclaration field) {
var ints = field.findAll(IntegerLiteralExpr.class);
switch (ints.size()) {
case 0 -> {
return OptionalInt.empty();
}
case 1 -> {
return OptionalInt.of(ints.get(0).asNumber().intValue());
}
default -> {
LOGGER.warn("Multiple integers found in version field declaration [{}]", field); // and ignore it
return OptionalInt.empty();
}
}
}
static void writeOutNewContents(Path file, CompilationUnit unit) throws IOException {
if (unit.containsData(LexicalPreservingPrinter.NODE_TEXT_DATA) == false) {
throw new IllegalArgumentException("CompilationUnit has no lexical information for output");
}
Files.writeString(file, LexicalPreservingPrinter.print(unit), StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);
}
}
View on GitHub (pinned to db6a809a66)
Solutions
- Ensure LexicalPreservingPrinter.setup(unit) is invoked right after parsing the source file and before any modification.
- Do not construct a CompilationUnit via 'new CompilationUnit()' for output that must preserve formatting — parse the real file and call setup.
- Re-run the release/version-rewrite task to confirm round-trip output is formatted correctly.
Example fix
// before CompilationUnit unit = StaticJavaParser.parse(file); // ... mutate unit ... writeOutNewContents(file, unit); // throws: no lexical info // after CompilationUnit unit = StaticJavaParser.parse(file); LexicalPreservingPrinter.setup(unit); // ... mutate unit ... writeOutNewContents(file, unit);
Defensive patterns
Strategy: validation
Validate before calling
CompilationUnit unit = StaticJavaParser.parse(file);
LexicalPreservingPrinter.setup(unit); // MUST precede any mutation
if (unit.containsData(LexicalPreservingPrinter.NODE_TEXT_DATA) == false) {
throw new IllegalStateException("LexicalPreservingPrinter not set up for " + file);
} Prevention
- Always call LexicalPreservingPrinter.setup(unit) immediately after parsing when round-trip printing is intended.
- Never use 'new CompilationUnit()' for files that must preserve original formatting.
- Add a helper that parses+setups to make the pairing impossible to forget.
When it happens
Trigger: A CompilationUnit is parsed (StaticJavaParser.parse) and modified, then passed to writeOutNewContents. The guard checks unit.containsData(LexicalPreservingPrinter.NODE_TEXT_DATA); if the caller forgot to call LexicalPreservingPrinter.setup(unit) immediately after parsing (before observing/altering the tree), the data key is absent and the throw fires.
Common situations: Adding a new code path that transforms a parsed Java file but omits the LexicalPreservingPrinter.setup call; refactoring an existing release-version-rewriting routine and dropping the setup line; using a fresh CompilationUnit built programmatically rather than parsed+setup for round-trip printing.
Related errors
- No version ids found in {javaVersionsFile}
- Invalid tag format [{l}]
- 'branch' not specified.
- Changelog directory contains changes that will be wiped out
- Failed to fetch branch {normalizedBranch} from {sourceRepo}
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/c3bede7fd6c2c438.
Report an issue: GitHub.