xai-org/x-algorithm · error · SemanticCheckFailure
Cannot load ThriftStruct Codec for %s: $s
Error message
Cannot load ThriftStruct Codec for %s: $s
What it means
To inspect a scrooge union/struct, getThriftStructCodec reflectively loads the companion class 'StructName$' and its MODULE$ codec. Any reflection failure (class missing, field missing, access error) is wrapped in SemanticCheckFailure.
Source
Thrown at botmaker/src/java/com/twitter/botmaker/compiler/types/ThriftStructType.java:350
} else if (ThriftEnum.class.isAssignableFrom(runtimeClass)) {
return new ThriftEnumMetaData((Class<? extends ThriftEnum>) runtimeClass);
} else {
throw new SemanticCheckFailure(
String.format("Unsupported field type %s", runtimeClass.toString()));
}
}
private static ThriftStructCodec getThriftStructCodec(
Class<? extends ThriftStruct> thriftClass) throws SemanticCheckFailure {
try {
Class<? extends ThriftStructCodec> codecClass =
(Class<? extends ThriftStructCodec>) ClassCache.forName(thriftClass.getName() + "$");
Field codecField = codecClass.getField("MODULE$");
ThriftStructCodec codec = (ThriftStructCodec) codecField.get(null);
return codec;
} catch (Exception e) {
throw new SemanticCheckFailure(
String.format("Cannot load ThriftStruct Codec for %s: $s",
thriftClass.getName(), e.toString()));
}
}
private static List<ThriftStructFieldInfo> getStructFieldInfos(
ThriftStructCodec codec) {
List<ThriftStructFieldInfo> fieldInfos =
JavaConverters.seqAsJavaList(codec.metaData().fieldInfos());
return fieldInfos;
}
private static List<ThriftStructFieldInfo> getUnionFieldInfos(
ThriftStructCodec codec) throws SemanticCheckFailure {
try {
Method fieldInfosMethod = codec.getClass().getMethod("fieldInfos");
List<ThriftUnionFieldInfo> fieldInfos =
JavaConverters.seqAsJavaList(View on GitHub (pinned to 24c60942c5)
Solutions
- Ensure the scrooge-generated class (and its 'StructName$' companion) for the exact schema version is on the classpath
- Regenerate thrift code with scrooge, not apache-thrift's generator
- Check for shading/relocation rules stripping or renaming companion objects
- Align botmaker and thrift artifact versions
Example fix
// before
// classpath contains apache-thrift generated MyStruct (no MODULE$)
Type t = TypeCompiler.getTypeFromClassName("com.acme.MyStruct");
// after
// depend on scrooge-generated MyStruct with MyStruct$ companion on classpath
Type t = TypeCompiler.getTypeFromClassName("com.acme.MyStruct"); Defensive patterns
Strategy: validation
Validate before calling
try {
Class.forName(thriftClassName + "$");
} catch (ClassNotFoundException e) { /* companion missing: bail early */ } Try / catch
catch SemanticCheckFailure starting with 'Cannot load ThriftStruct Codec' and report a classpath/version problem rather than a rule error
Prevention
- Deploy scrooge-generated classes and botmaker together
- Add a startup check loading companions for all referenced structs
When it happens
Trigger: ClassCache.forName(thriftClass.getName() + "$") failing — the companion object class is absent from the classpath, shaded/renamed, or the thrift class is not scrooge-generated (e.g. apache-thrift generated, which has no MODULE$).
Common situations: Version mismatch between the thrift-generated jar and the botmaker compiler; proguard/shading stripping companion objects; using apache-thrift generated classes where scrooge classes are expected; classloader isolation in app servers.
Related errors
- Failed to create serializer for ThriftStruct %s: %s
- Cannot load ThriftUnion fieldInfos for %s: $s
- cannot find class %s
- class to be imported has to be either a TBase or ThriftStruc
- cannot find class %s
AI-assisted analysis of xai-org/x-algorithm@24c60942c5 (2026-08-28).
Data as JSON: /api/errors/6f524ef5904d3898.
Report an issue: GitHub.