{"record":{"id":"43085f37972c7afd","repo":"apache/dolphinscheduler","slug":"cannot-merge-json-message-to-protobuf-definition-t","errorCode":null,"errorMessage":"cannot merge json message to protobuf definition type <messageTypeName>","messagePattern":"cannot merge json message to protobuf definition type <messageTypeName>","errorType":"exception","errorClass":"GrpcParserException","httpStatus":null,"severity":"error","filePath":"dolphinscheduler-task-plugin/dolphinscheduler-task-grpc/src/main/java/org/apache/dolphinscheduler/plugin/task/grpc/protobufjs/GrpcDynamicService.java","lineNumber":74,"sourceCode":"        if (isNull(pServiceDescriptor))\n            throw new GrpcParserException(\n                    \"cannot find service <\" + methodNameData.getServiceName() + \"> from service definition\");\n        Descriptors.MethodDescriptor pMethodDescriptor =\n                pServiceDescriptor.findMethodByName(methodNameData.getRpcName());\n        if (isNull(pMethodDescriptor))\n            throw new GrpcParserException(\"cannot find method <\" + methodNameData.getRpcName() + \"> from service <\"\n                    + methodNameData.getServiceName() + \"> with method list: \" + Arrays.toString(pServiceDescriptor\n                            .getMethods().stream().map(Descriptors.MethodDescriptor::getName).toArray()));\n        MethodDescriptor<DynamicMessage, DynamicMessage> methodDescriptor =\n                methodFromProtobuf(pServiceDescriptor, pMethodDescriptor);\n        Descriptors.Descriptor requestMessageType = pMethodDescriptor.getInputType();\n        Descriptors.Descriptor responseMessageType = pMethodDescriptor.getOutputType();\n        DynamicMessage.Builder requestBuilder = DynamicMessage.newBuilder(requestMessageType);\n        DynamicMessage.Builder responseBuilder = DynamicMessage.newBuilder(responseMessageType);\n        try {\n            JsonFormat.parser().ignoringUnknownFields().merge(messageJSON, requestBuilder);\n        } catch (InvalidProtocolBufferException ipbe) {\n            throw new GrpcParserException(\n                    \"cannot merge json message to protobuf definition type <\" + requestMessageType.getName() + \">\",\n                    ipbe);\n        }\n        DynamicMessage request = requestBuilder.build();\n        CallOptions callOptions = timeout > 0 ? CallOptions.DEFAULT.withDeadlineAfter(timeout, TimeUnit.MILLISECONDS)\n                : CallOptions.DEFAULT;\n        responseBuilder.mergeFrom(\n                io.grpc.stub.ClientCalls.blockingUnaryCall(channel, methodDescriptor, callOptions, request));\n        return responseBuilder.build();\n    }\n\n    public static DynamicMessage mergeJSON(Descriptors.FileDescriptor fileDesc, String methodNameWithService,\n                                           String messageJSON) {\n        MethodName methodNameData = new MethodName(methodNameWithService);\n        Descriptors.ServiceDescriptor pServiceDescriptor =\n                fileDesc.findServiceByName(methodNameData.getServiceName());\n        if (isNull(pServiceDescriptor))\n            throw new GrpcParserException(","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/apache/dolphinscheduler/blob/02eac45a1b6676e639fcbfb4be2243de5771b05d/dolphinscheduler-task-plugin/dolphinscheduler-task-grpc/src/main/java/org/apache/dolphinscheduler/plugin/task/grpc/protobufjs/GrpcDynamicService.java#L56-L92","documentation":"call() merges the user-supplied JSON into a DynamicMessage.Builder for the request type using protobuf's JsonFormat parser. If the JSON is not valid for the protobuf request message type (invalid JSON syntax or type mismatches that cannot be coerced), the InvalidProtocolBufferException is wrapped in GrpcParserException naming the request message type. Note unknown fields are ignored, so only syntax errors and non-coercible value types trigger this.","triggerScenarios":"Passing messageJSON that is not syntactically valid JSON (e.g. trailing commas, single quotes, unquoted keys), or whose field values cannot be converted to the proto types (e.g. a string where the proto expects an int32, an object where a string is expected, malformed bytes/base64).","commonSituations":"Building the JSON payload by string concatenation in the task config instead of a proper JSON serializer; wrong field types after a proto change; numeric fields given as non-numeric strings; passing a JSON array where the request message expects an object.","solutions":["Validate that messageJSON parses as strict JSON (use a JSON linter or JSON.parse) and fix syntax errors like trailing commas or single quotes.","Compare each JSON field's type with the request message definition named in the error and convert values (e.g. '123' -> 123 for int fields).","Remove JSON fields that conflict with proto field types; rely on ignoringUnknownFields() for extra fields but not for mistyped known fields.","Generate the payload with a JSON serializer from a map/object rather than hand-writing or concatenating strings."],"exampleFix":"// before\nString json = \"{id: 'abc', retries: '3'}\"; // unquoted key, string for int32\n// after\nString json = \"{\\\"id\\\": \\\"abc\\\", \\\"retries\\\": 3}\";","handlingStrategy":"validation","validationCode":"// Validate JSON before calling:\ntry {\n    new com.fasterxml.jackson.databind.ObjectMapper().readTree(messageJSON);\n} catch (IOException e) {\n    throw new IllegalArgumentException(\"messageJSON is not valid JSON\", e);\n}\n// Additionally confirm field value types match the proto request definition.","typeGuard":null,"tryCatchPattern":"try {\n    dynamicService.call(methodNameWithService, messageJSON, timeout);\n} catch (GrpcParserException e) {\n    if (e.getMessage().startsWith(\"cannot merge json message\") && e.getCause() instanceof InvalidProtocolBufferException) {\n        // fix JSON syntax or field types for the named request message type\n    }\n    throw e;\n}","preventionTips":["Always produce request JSON with a serializer (Jackson/Gson), never string concatenation.","Check field types in the JSON against the proto message definition (numbers for numeric fields, strings for string fields).","Remember unknown fields are ignored but mistyped known fields are not — remove or fix conflicting fields.","Validate the JSON with a linter/parser before submitting the task."],"tags":["grpc","protobuf","json","validation"],"backgroundTag":"json-marshal-failed","analyzedSha":"02eac45a1b6676e639fcbfb4be2243de5771b05d","analyzedAt":"2026-09-06T17:43:00.555Z","contentChangedAt":"2026-09-06T17:43:00.555Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}