{"record":{"id":"95011ed1abcf3242","repo":"apache/shenyu","slug":"build-json-response-message-is-error-newbuilder-method-is","errorCode":null,"errorMessage":"build json response message is error, newBuilder method is null","messagePattern":"build json response message is error, newBuilder method is null","errorType":"exception","errorClass":"ShenyuException","httpStatus":null,"severity":"error","filePath":"shenyu-client/shenyu-client-grpc/src/main/java/org/apache/shenyu/client/grpc/json/JsonServerCallListener.java","lineNumber":70,"sourceCode":"    }\n\n    @Override\n    protected Listener<R> delegate() {\n        return delegate;\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    @Override\n    public void onMessage(final R message) {\n        Message.Builder builder;\n        Class<?> t = JsonServerServiceInterceptor.getRequestClazzMap().get(call.getMethodDescriptor().getFullMethodName());\n        try {\n            builder = (Message.Builder) ReflectUtils.invokeStaticMethod(t, \"newBuilder\");\n\n            String reqData = JsonMessage.getDataFromDynamicMessage((DynamicMessage) message);\n            JsonFormat.parser().ignoringUnknownFields().merge(reqData, builder);\n            if (Objects.isNull(builder)) {\n                throw new ShenyuException(\"build json response message is error, newBuilder method is null\");\n            }\n\n            delegate.onMessage((R) builder.build());\n        } catch (Exception e) {\n            throw Status.INTERNAL.withDescription(e.getMessage()).asRuntimeException();\n        }\n    }\n\n    @Override\n    public void onHalfClose() {\n        super.onHalfClose();\n    }\n\n    @Override\n    public void onCancel() {\n        super.onCancel();\n    }\n","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/apache/shenyu/blob/567142e07261b3e615ae8850b30f4421f455cc5d/shenyu-client/shenyu-client-grpc/src/main/java/org/apache/shenyu/client/grpc/json/JsonServerCallListener.java#L52-L88","documentation":"JsonServerCallListener.onMessage converts incoming protobuf DynamicMessage to JSON and back. It reflectively calls newBuilder() on the message type to obtain a Builder; the guard checks the builder is null afterwards and throws ShenyuException. In practice the reflective invokeStaticMethod throws (caught by the outer catch) or the type has no newBuilder, so JSON translation of the gRPC message fails and the call is aborted with Status.INTERNAL.","triggerScenarios":"A gRPC request/response message whose class does not expose a static newBuilder() method (non-Message types, proto3 gencode mismatches, or classes not generated by protoc), during json-mode gRPC proxying.","commonSituations":"Gateway json-transcoding a service whose proto classes were compiled with an incompatible protobuf version; messages not actually protobuf-generated classes; grpc version upgrades changing reflection behavior.","solutions":["Verify the proxied service uses protobuf-generated Message classes with a static newBuilder()","Align protobuf/grpc versions between gateway and backend service","Check the wrapped Status.INTERNAL description/logs for the underlying reflection exception","Regenerate stubs from the correct .proto files if gencode mismatched"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if (!Message.class.isAssignableFrom(requestType)\n        || requestType.getMethod(\"newBuilder\") == null) {\n    throw new IllegalStateException(requestType + \" is not a protobuf-generated message\");\n}","typeGuard":null,"tryCatchPattern":"try { jsonListener.onMessage(message); }\ncatch (StatusRuntimeException e) {\n    log.error(\"json transcoding failed: {}\", e.getStatus().getDescription());\n}","preventionTips":["Only proxy protobuf-generated services in json mode","Keep protobuf/grpc versions aligned between gateway and backend","Regenerate stubs after proto changes"],"tags":["grpc","protobuf","reflection","json-transcoding"],"backgroundTag":"protobuf-unmarshal-failed","analyzedSha":"567142e07261b3e615ae8850b30f4421f455cc5d","analyzedAt":"2026-09-12T10:08:21.293Z","contentChangedAt":"2026-09-12T10:08:21.293Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}