{"record":{"id":"dde2dec0d57e027d","repo":"apache/dubbo","slug":"generic-serialization-s-json-syntax-exception-t-dde2de","errorCode":null,"errorMessage":"Generic serialization [%s] Json syntax exception thrown when parsing (object:%s ) error:%s","messagePattern":"Generic serialization \\[(.+?)\\] Json syntax exception thrown when parsing \\(object:(.+?) \\) error:(.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"dubbo-common/src/main/java/org/apache/dubbo/common/json/GsonUtils.java","lineNumber":72,"sourceCode":"        }\n        Type type = TypeToken.get(originType).getType();\n        try {\n            return getGson().fromJson(json, type);\n        } catch (JsonSyntaxException ex) {\n            throw new RuntimeException(String.format(\n                    \"Generic serialization [%s] Json syntax exception thrown when parsing (message:%s type:%s) error:%s\",\n                    GENERIC_SERIALIZATION_GSON, json, type.toString(), ex.getMessage()));\n        }\n    }\n\n    public static String toJson(Object obj) throws RuntimeException {\n        if (!isSupportGson()) {\n            throw new RuntimeException(\"Gson is not supported. Please import Gson in JVM env.\");\n        }\n        try {\n            return getGson().toJson(obj);\n        } catch (JsonSyntaxException ex) {\n            throw new RuntimeException(String.format(\n                    \"Generic serialization [%s] Json syntax exception thrown when parsing (object:%s ) error:%s\",\n                    GENERIC_SERIALIZATION_GSON, obj, ex.getMessage()));\n        }\n    }\n\n    private static Gson getGson() {\n        if (gsonCache == null || !(gsonCache instanceof Gson)) {\n            synchronized (GsonUtils.class) {\n                if (gsonCache == null || !(gsonCache instanceof Gson)) {\n                    gsonCache = new Gson();\n                }\n            }\n        }\n        return (Gson) gsonCache;\n    }\n\n    /**\n     * @deprecated for uts only","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-common/src/main/java/org/apache/dubbo/common/json/GsonUtils.java#L54-L90","documentation":"Thrown by GsonUtils.toJson(Object) when Gson raises a JsonSyntaxException while serializing the object. Although serialization failures are rarer than parse failures, Gson can throw on non-serializable graphs (e.g. circular references, fields whose types have no adapter, or objects whose toString/adapter throws). Dubbo wraps it in a RuntimeException with a diagnostic including the generic-serialization tag, the object, and Gson's message. The label says 'parsing' but this is the serialization path.","triggerScenarios":"GsonUtils.toJson(obj) where obj contains a circular reference, a field of a type Gson cannot handle (e.g. a JDK type with no adapter, a Throwable/lambda), a custom serializer that throws, or a value that breaks Gson's reflective field access. toJson is only reached after isSupportGson() passes, so Gson is present.","commonSituations":"Passing a domain object with bidirectional parent/child links (circular) to a generic call; serializing an object holding non-JSON-friendly JDK types (InputStream, Connection); a field whose getter/field throws during reflection; mixing Gson with a DTO designed for a different serializer (Hessian/Kryo) whose types have no Gson mapping.","solutions":["Inspect the object graph for circular references and break them (transient fields, @JsonAdapter adapters, or DTOs that flatten the cycle).","For non-serializable fields, exclude them with Gson's transient modifier or a custom ExclusionStrategy / TypeAdapter.","Map the runtime object to a JSON-safe DTO before calling toJson.","Catch the RuntimeException at the invocation boundary and convert to a domain-level error."],"exampleFix":"// before\nString json = GsonUtils.toJson(entity); // entity has circular parent->child->parent\n// after - flatten to a DTO with no back-references\nString json = GsonUtils.toJson(EntityDto.from(entity));","handlingStrategy":"try-catch","validationCode":"// Detect likely-unsafe graphs before serializing: check for circular references or non-JSON fields.\n// Gson has no built-in pre-check; prefer mapping to a JSON-safe DTO instead.","typeGuard":null,"tryCatchPattern":"try {\n    return GsonUtils.toJson(obj);\n} catch (RuntimeException e) {\n    // message format: \"Generic serialization [gson] Json syntax exception ... (object:%s ) error:%s\"\n    log.error(\"gson toJson failed for object {}\", obj, e);\n    throw new RpcException(\"Failed to serialize object via gson\", e);\n}","preventionTips":["Break circular references in domain objects before serializing (use transient fields or DTOs).","Exclude non-serializable JDK fields (InputStream, Connection) via transient or a custom adapter.","Map domain objects to JSON-safe DTOs rather than serializing rich entities directly.","Catch the RuntimeException at the invocation boundary and convert to a domain error."],"tags":["json","gson","serialization","generic-invocation","dubbo-common"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}