elastic/elasticsearch · error · RuntimeException
TransportVersion.fromName must be called with a non-empty St
Error message
TransportVersion.fromName must be called with a non-empty String literal. See {}. What it means
RuntimeException from CollectTransportVersionReferencesTask's ASM bytecode visitor. It scans compiled classes for calls to TransportVersion.fromName(...) and requires the argument to be a non-empty LDC string literal (a compile-time constant). Any other shape (variable, method call result, computed value, or empty literal) is rejected because the static analysis cannot record a stable transport-version name.
Source
Thrown at build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/transport/CollectTransportVersionReferencesTask.java:121
@Override
public void visitLabel(Label label) {
// asm uses many debug labels that we do not want to consider
// so we ignore labels so they do not become part of the instructions list
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) {
if (owner.equals(TRANSPORT_VERSION_SET_CLASS) && name.equals(TRANSPORT_VERSION_SET_METHOD_NAME)) {
var abstractInstruction = this.instructions.getLast();
String location = classname + " line " + lineNumber;
if (abstractInstruction instanceof LdcInsnNode ldcInsnNode
&& ldcInsnNode.cst instanceof String tvName
&& tvName.isEmpty() == false) {
results.add(new TransportVersionReference(tvName, location));
} else {
// The instruction is not a LDC with a String constant (or an empty String), which is not allowed.
throw new RuntimeException(
"TransportVersion.fromName must be called with a non-empty String literal. " + "See " + location + "."
);
}
}
super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
}
};
}
};
ClassReader classReader = new ClassReader(classBytes);
classReader.accept(classVisitor, 0);
}
private static String classname(String filename) {
return filename.substring(0, filename.length() - CLASS_EXTENSION.length()).replaceAll("[/\\\\]", ".");
}
}
View on GitHub (pinned to db6a809a66)
Solutions
- Locate the call at the reported 'classname line N' and replace the argument with a non-empty string literal.
- If a shared constant is needed, make it a compile-time constant (static final String literal) so javac inlines it as LDC.
- Never pass dynamically-computed strings to TransportVersion.fromName.
Example fix
// before
TransportVersion v = TransportVersion.fromName(versionNameFromConfig);
// after
TransportVersion v = TransportVersion.fromName("my_feature_v1"); Defensive patterns
Strategy: validation
Validate before calling
// Static-analysis guard in source: only allow string literals
static final Set<String> ALLOWED = Set.of("feature_a_v1", "feature_b_v1");
void register(String name) {
if (name == null || name.isEmpty() || !ALLOWED.contains(name)) {
throw new IllegalArgumentException("TransportVersion name must be a known literal: " + name);
}
TransportVersion.fromName(name);
} Type guard
// Compile-time-ish guard: prevent dynamic names at review time
static void assertLiteral(String name) {
if (name == null || name.isEmpty()) throw new IllegalArgumentException("empty name");
} Prevention
- Always pass a string literal to TransportVersion.fromName.
- Use static final String constants so javac inlines them to LDC.
- Never read version names from config/env at the call site.
When it happens
Trigger: Source code calls TransportVersion.fromName(someVariable), TransportVersion.fromName(""), or passes a concatenated/computed string; ASM's last instruction before the call is not an LdcInsnNode with a String constant.
Common situations: Refactoring a fromName call to use a constant field or a computed value; copy-pasting a fromName placeholder with an empty string; using a non-final String field (not inlined to LDC).
Related errors
- Unexpected class file version ${rawVersion} for ${cn.name} (
- Invalid increment {}, must be a positive integer
- Invalid increment {}, must be no larger than 1000
- Could not find base id: {}
- Missing upper bound {} for release version {}
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/128557a90317aa06.
Report an issue: GitHub.