{"record":{"id":"d600012d83e00041","repo":"xai-org/x-algorithm","slug":"failed-to-create-serializer-for-thriftstruct-s","errorCode":null,"errorMessage":"Failed to create serializer for ThriftStruct %s: %s","messagePattern":"Failed to create serializer for ThriftStruct (.+?): (.+?)","errorType":"exception","errorClass":"SemanticCheckFailure","httpStatus":null,"severity":"error","filePath":"botmaker/src/java/com/twitter/botmaker/compiler/Serializer.java","lineNumber":1626,"sourceCode":"\n        @Override\n        protected T deserialize(TProtocol prot) throws TException {\n          return (T) codec.decode(prot);\n        }\n\n        @Override\n        protected void toScript(GenScript script, T value) {\n          script.builder.append(\"NULL\");\n        }\n\n        @Override\n        protected void toStratoJson(GenScript script, T value) {\n          throw new IllegalArgumentException(\n              \"Thriftscala objects are not supported in strato JSON\");\n        }\n      };\n    } catch (Exception e) {\n      throw new SemanticCheckFailure(\n          String.format(\"Failed to create serializer for ThriftStruct %s: %s\",\n              clazz.getName(), e.toString())\n      );\n    }\n  }\n\n  private static final class TByteBufferTransport extends TTransport {\n    private ByteBuffer buffer;\n\n    public TByteBufferTransport(ByteBuffer buf) {\n      this.buffer = buf;\n    }\n\n    @Override\n    public void close() {\n    }\n\n    @Override","sourceCodeStart":1608,"sourceCodeEnd":1644,"githubUrl":"https://github.com/xai-org/x-algorithm/blob/24c60942c5c5fdad3a6addffb4c6e6d2f228f04f/botmaker/src/java/com/twitter/botmaker/compiler/Serializer.java#L1608-L1644","documentation":"thriftStructOf wraps its reflective construction of a scrooge-struct serializer in try/catch; any exception while reflecting over the class (finding companion apply/unapply methods, fields, annotations) is rethrown as SemanticCheckFailure with the class name and the original exception's toString. It signals that the compiler could not build a serializer for the named ThriftStruct, and the cause string is the key diagnostic.","triggerScenarios":"Calling Serializer.thriftStructOf(clazz) where clazz lacks the expected scrooge structure: missing companion object, inaccessible fields, classpath mismatch between thriftscala versions, or LinkageError/ClassNotFoundException during reflection.","commonSituations":"Thrift codegen version drift (scrooge version X structs inspected by a compiler expecting version Y); shaded/duplicate classes on the classpath; structs generated with different scrooge options; proguard/obfuscation stripping companion methods; passing a non-scrooge class that merely implements ThriftStruct.","solutions":["Read the %s cause in the message (the wrapped exception's toString) — NoClassDefFoundError/NoSuchMethodException points to version skew, IllegalAccess points to visibility.","Align the scrooge/thrift codegen version that produced clazz with the version this compiler expects, and rebuild the structs.","Verify the class actually is a scrooge-generated ThriftStruct with a usable companion object (not a hand-written implementation).","Check for duplicate/shaded copies of the struct class on the classpath (dependency:tree / classpath:dump) and exclude the stale one."],"exampleFix":"// before\nSerializer.thriftStructOf(clazz); // Failed to create serializer for ThriftStruct com.example.MyStruct: java.lang.NoSuchMethodException\n\n// after\n// regenerate structs with matching scrooge version, then:\nPreconditions.checkArgument(isScroogeGenerated(clazz), \"not a scrooge struct: %s\", clazz);\nSerializer.thriftStructOf(clazz);","handlingStrategy":"try-catch","validationCode":"try {\n  Object companion = clazz.getMethod(\"companion\").invoke(null); // smoke-check scrooge shape\n} catch (ReflectiveOperationException ex) {\n  throw new IllegalArgumentException(clazz + \" is not scrooge-generated\", ex);\n}","typeGuard":"static boolean isScroogeStruct(Class<?> c) {\n  return ThriftStruct.class.isAssignableFrom(c)\n      && hasCompanionApply(c);\n}","tryCatchPattern":"catch (SemanticCheckFailure e) {\n  log.error(\"serializer init failed for {}: {}\", className, e.getMessage());\n  failRuleCompilationWithDiagnostics(e); // surface as user-facing rule error\n}","preventionTips":["Pin scrooge/thrift codegen versions across the build.","Fail fast at startup by pre-building serializers for all registered struct types.","Check for duplicate/shaded struct classes when this appears after dependency changes.","Read the wrapped cause toString — it names the actual reflective failure."],"tags":["thrift","scrooge","reflection","version-skew","semantic-check","java"],"backgroundTag":"reflection-based-serializer-init-failed","analyzedSha":"24c60942c5c5fdad3a6addffb4c6e6d2f228f04f","analyzedAt":"2026-08-28T11:40:14.686Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}