{"record":{"id":"6f524ef5904d3898","repo":"xai-org/x-algorithm","slug":"cannot-load-thriftstruct-codec-for-s-s","errorCode":null,"errorMessage":"Cannot load ThriftStruct Codec for %s: $s","messagePattern":"Cannot load ThriftStruct Codec for (.+?): \\$s","errorType":"exception","errorClass":"SemanticCheckFailure","httpStatus":null,"severity":"error","filePath":"botmaker/src/java/com/twitter/botmaker/compiler/types/ThriftStructType.java","lineNumber":350,"sourceCode":"    } else if (ThriftEnum.class.isAssignableFrom(runtimeClass)) {\n      return new ThriftEnumMetaData((Class<? extends ThriftEnum>) runtimeClass);\n    } else {\n      throw new SemanticCheckFailure(\n          String.format(\"Unsupported field type %s\", runtimeClass.toString()));\n    }\n  }\n\n  private static ThriftStructCodec getThriftStructCodec(\n      Class<? extends ThriftStruct> thriftClass) throws SemanticCheckFailure {\n\n    try {\n      Class<? extends ThriftStructCodec> codecClass =\n          (Class<? extends ThriftStructCodec>) ClassCache.forName(thriftClass.getName() + \"$\");\n      Field codecField = codecClass.getField(\"MODULE$\");\n      ThriftStructCodec codec = (ThriftStructCodec) codecField.get(null);\n      return codec;\n    } catch (Exception e) {\n      throw new SemanticCheckFailure(\n          String.format(\"Cannot load ThriftStruct Codec for %s: $s\",\n              thriftClass.getName(), e.toString()));\n    }\n  }\n\n  private static List<ThriftStructFieldInfo> getStructFieldInfos(\n      ThriftStructCodec codec) {\n    List<ThriftStructFieldInfo> fieldInfos =\n        JavaConverters.seqAsJavaList(codec.metaData().fieldInfos());\n    return fieldInfos;\n  }\n\n  private static List<ThriftStructFieldInfo> getUnionFieldInfos(\n      ThriftStructCodec codec) throws SemanticCheckFailure {\n    try {\n      Method fieldInfosMethod = codec.getClass().getMethod(\"fieldInfos\");\n      List<ThriftUnionFieldInfo> fieldInfos =\n          JavaConverters.seqAsJavaList(","sourceCodeStart":332,"sourceCodeEnd":368,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/botmaker/src/java/com/twitter/botmaker/compiler/types/ThriftStructType.java#L332-L368","documentation":"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.","triggerScenarios":"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$).","commonSituations":"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.","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"],"exampleFix":"// before\n// classpath contains apache-thrift generated MyStruct (no MODULE$)\nType t = TypeCompiler.getTypeFromClassName(\"com.acme.MyStruct\");\n// after\n// depend on scrooge-generated MyStruct with MyStruct$ companion on classpath\nType t = TypeCompiler.getTypeFromClassName(\"com.acme.MyStruct\");","handlingStrategy":"validation","validationCode":"try {\n  Class.forName(thriftClassName + \"$\");\n} catch (ClassNotFoundException e) { /* companion missing: bail early */ }","typeGuard":null,"tryCatchPattern":"catch SemanticCheckFailure starting with 'Cannot load ThriftStruct Codec' and report a classpath/version problem rather than a rule error","preventionTips":["Deploy scrooge-generated classes and botmaker together","Add a startup check loading companions for all referenced structs"],"tags":["thrift","scrooge","classpath","reflection"],"backgroundTag":"class-not-found-on-classpath","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}