{"record":{"id":"dcafe1d37b5eacfc","repo":"floci-io/floci","slug":"invalid-json","errorCode":null,"errorMessage":"Invalid JSON: {}","messagePattern":"Invalid JSON: (.+?)","errorType":"validation","errorClass":"CoercingParseValueException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/github/hectorvent/floci/services/appsync/graphql/scalars/AppSyncScalars.java","lineNumber":47,"sourceCode":"        .description(\"A JSON string\")\n        .coercing(new Coercing<String, String>() {\n            @Override\n            public String serialize(Object dataFetcherResult) {\n                if (dataFetcherResult == null) return null;\n                if (dataFetcherResult instanceof String s) return s;\n                try {\n                    return SHARED_MAPPER.writeValueAsString(dataFetcherResult);\n                } catch (JsonProcessingException e) {\n                    throw new CoercingSerializeException(\"Cannot serialize to JSON: \" + e.getMessage());\n                }\n            }\n            @Override\n            public String parseValue(Object input) {\n                String str = input.toString();\n                try {\n                    SHARED_MAPPER.readTree(str);\n                } catch (Exception e) {\n                    throw new CoercingParseValueException(\"Invalid JSON: \" + str);\n                }\n                return str;\n            }\n            @Override\n            public String parseLiteral(Object input) {\n                if (!(input instanceof StringValue sv)) return null;\n                return parseValue(sv.getValue());\n            }\n        })\n        .build();\n\n    public static final GraphQLScalarType AWS_DATE_TIME = GraphQLScalarType.newScalar()\n        .name(\"AWSDateTime\")\n        .description(\"An ISO-8601 datetime string\")\n        .coercing(new Coercing<String, String>() {\n            @Override\n            public String serialize(Object dataFetcherResult) {\n                return dataFetcherResult != null ? dataFetcherResult.toString() : null;","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/floci-io/floci/blob/62ff490619e7bd3554597c28c704081b4c15add5/src/main/java/io/github/hectorvent/floci/services/appsync/graphql/scalars/AppSyncScalars.java#L29-L65","documentation":"Thrown by the AWSJSON scalar's parseValue when the incoming GraphQL variable or literal value is not parseable JSON. The scalar accepts a JSON-encoded string, so the coercion first validates it by calling Jackson's readTree on the raw string; any parse failure means the client did not send a valid JSON document inside the string.","triggerScenarios":"A GraphQL mutation/query against the AppSync emulator passing an AWSJSON variable whose string content is malformed, e.g. variables {\"input\": {\"data\": \"{not json}\"}} or unbalanced braces/quotes. Also triggered from parseLiteral when the query document contains a StringValue whose text is not valid JSON.","commonSituations":"Client builds the JSON payload by manual string concatenation instead of a JSON serializer; double-escaping mistakes (sending {\"a\":1} escaped one time too few/many); passing a plain string or object where a JSON-encoded string is expected; template literals with embedded quotes.","solutions":["Serialize the payload with a real JSON library (Jackson/ObjectMapper.writeValueAsString, JSON.stringify) instead of hand-building the string","Check the value round-trips: ObjectMapper.readValue(s, Object.class) before sending","Verify escaping: the variable value must be a string that itself contains valid JSON, e.g. \"{\\\"a\\\":1}\"","Add a client-side unit test that validates every AWSJSON field with a JSON parser before the request"],"exampleFix":"// before\nMap<String,String> vars = Map.of(\"data\", \"{id: 1}\"); // invalid JSON\n\n// after\nString json = new ObjectMapper().writeValueAsString(Map.of(\"id\", 1));\nMap<String,String> vars = Map.of(\"data\", json); // \"{\\\"id\\\":1}\"","handlingStrategy":"validation","validationCode":"ObjectMapper m = new ObjectMapper();\nboolean isAwsJson = false;\ntry { m.readTree(value); isAwsJson = true; } catch (Exception ignored) {}\nif (!isAwsJson) throw new IllegalArgumentException(\"data must be a valid JSON-encoded string\");\nvars.put(\"data\", m.writeValueAsString(payload)); // build with the mapper","typeGuard":"// JS\nconst isAwsJson = (s) => { try { JSON.parse(s); return true; } catch { return false; } };","tryCatchPattern":"catch (CoercingParseValueException e) { /* field-level GraphQL error: surface the message, it echoes the offending string */ }","preventionTips":["Always build AWSJSON values with a JSON serializer, never string concatenation","Round-trip check: parse the string back before sending","Keep escaping single-level: the variable is a string containing JSON, nothing more"],"tags":["graphql","appsync","awsjson","validation","scalars"],"backgroundTag":null,"analyzedSha":"62ff490619e7bd3554597c28c704081b4c15add5","analyzedAt":"2026-08-14T14:25:23.764Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}