{"record":{"id":"296ab7d3bd3736d6","repo":"apache/shenyu","slug":"the-date-should-be-a-string-value","errorCode":null,"errorMessage":"The date should be a string value","messagePattern":"The date should be a string value","errorType":"exception","errorClass":"JsonParseException","httpStatus":null,"severity":"error","filePath":"shenyu-common/src/main/java/org/apache/shenyu/common/utils/GsonUtils.java","lineNumber":515,"sourceCode":"                if (reader.peek() == JsonToken.NULL) {\n                    reader.nextNull();\n                    return null;\n                }\n                return Duration.parse(reader.nextString());\n            } catch (IOException e) {\n                throw new ShenyuException(e);\n            }\n        }\n    }\n    \n    private static class TimestampTypeAdapter implements JsonSerializer<Timestamp>, JsonDeserializer<Timestamp> {\n\n        private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern(\"yyyy-MM-dd HH:mm:ss\");\n\n        @Override\n        public Timestamp deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context) throws JsonParseException {\n            if (!(json instanceof JsonPrimitive)) {\n                throw new JsonParseException(\"The date should be a string value\");\n            }\n            try {\n                LocalDateTime dateTime = FORMATTER.parse(json.getAsString(), LocalDateTime::from);\n                return Timestamp.valueOf(dateTime);\n            } catch (Exception e) {\n                throw new JsonParseException(e);\n            }\n        }\n\n        @Override\n        public JsonElement serialize(final Timestamp src, final Type typeOfSrc, final JsonSerializationContext context) {\n            LocalDateTime ldt = LocalDateTime.ofInstant(src.toInstant(), ZoneId.systemDefault());\n            String formatted = FORMATTER.format(ldt);\n            return new JsonPrimitive(formatted);\n        }\n    }\n}\n","sourceCodeStart":497,"sourceCodeEnd":533,"githubUrl":"https://github.com/apache/shenyu/blob/567142e07261b3e615ae8850b30f4421f455cc5d/shenyu-common/src/main/java/org/apache/shenyu/common/utils/GsonUtils.java#L497-L533","documentation":"GsonUtils' Timestamp deserializer expects the JSON value to be a JsonPrimitive string formatted as 'yyyy-MM-dd HH:mm:ss'. If the JSON element is not a primitive (object, array, null) it throws JsonParseException with this message, because only a string can be parsed into a Timestamp.","triggerScenarios":"Deserializing JSON where a field mapped to java.sql.Timestamp is a JSON object/array/null instead of a quoted string, e.g. {\"createdAt\": {}} or {\"createdAt\": null} passed through GsonUtils.fromJson with a Timestamp-typed target.","commonSituations":"Upstream API changed a date field from string to object; sending JSON with null Timestamp field; hand-written JSON forgetting quotes around the date; GraphQL-ish nested payloads fed into admin DTOs.","solutions":["Send the date as a quoted string in 'yyyy-MM-dd HH:mm:ss' format.","Make the target field String or a wrapper type and parse manually if the shape can vary.","Register a custom deserializer (or use GsonUtils' built-in one) that handles null/object shapes defensively.","Validate the JSON payload before deserialization."],"exampleFix":"// before\n{\"createdAt\": null}\n// after\n{\"createdAt\": \"2026-09-12 10:15:30\"}","handlingStrategy":"validation","validationCode":"JsonElement el = obj.get(\"createdAt\"); if (el == null || !el.isJsonPrimitive() || !el.getAsJsonPrimitive().isString()) throw new IllegalArgumentException(\"createdAt must be 'yyyy-MM-dd HH:mm:ss' string\");","typeGuard":"boolean isTimestampString(JsonElement el) { return el != null && el.isJsonPrimitive() && el.getAsJsonPrimitive().isString(); }","tryCatchPattern":"try { Timestamp ts = gson.fromJson(json, Target.class); } catch (JsonParseException e) { LOG.error(\"bad timestamp payload\", e); }","preventionTips":["Always serialize timestamps as quoted 'yyyy-MM-dd HH:mm:ss' strings","Contract-test payloads against deserialization","Use GsonUtils registered serializers consistently on both sides","Reject null date fields at API validation layer"],"tags":["json","gson","deserialization","timestamp","date"],"backgroundTag":"json-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"}