floci-io/floci · error · CoercingParseValueException

Invalid JSON: {}

Error message

Invalid JSON: {}

What it means

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.

Source

Thrown at src/main/java/io/github/hectorvent/floci/services/appsync/graphql/scalars/AppSyncScalars.java:47

        .description("A JSON string")
        .coercing(new Coercing<String, String>() {
            @Override
            public String serialize(Object dataFetcherResult) {
                if (dataFetcherResult == null) return null;
                if (dataFetcherResult instanceof String s) return s;
                try {
                    return SHARED_MAPPER.writeValueAsString(dataFetcherResult);
                } catch (JsonProcessingException e) {
                    throw new CoercingSerializeException("Cannot serialize to JSON: " + e.getMessage());
                }
            }
            @Override
            public String parseValue(Object input) {
                String str = input.toString();
                try {
                    SHARED_MAPPER.readTree(str);
                } catch (Exception e) {
                    throw new CoercingParseValueException("Invalid JSON: " + str);
                }
                return str;
            }
            @Override
            public String parseLiteral(Object input) {
                if (!(input instanceof StringValue sv)) return null;
                return parseValue(sv.getValue());
            }
        })
        .build();

    public static final GraphQLScalarType AWS_DATE_TIME = GraphQLScalarType.newScalar()
        .name("AWSDateTime")
        .description("An ISO-8601 datetime string")
        .coercing(new Coercing<String, String>() {
            @Override
            public String serialize(Object dataFetcherResult) {
                return dataFetcherResult != null ? dataFetcherResult.toString() : null;

View on GitHub (pinned to 62ff490619)

Solutions

  1. Serialize the payload with a real JSON library (Jackson/ObjectMapper.writeValueAsString, JSON.stringify) instead of hand-building the string
  2. Check the value round-trips: ObjectMapper.readValue(s, Object.class) before sending
  3. Verify escaping: the variable value must be a string that itself contains valid JSON, e.g. "{\"a\":1}"
  4. Add a client-side unit test that validates every AWSJSON field with a JSON parser before the request

Example fix

// before
Map<String,String> vars = Map.of("data", "{id: 1}"); // invalid JSON

// after
String json = new ObjectMapper().writeValueAsString(Map.of("id", 1));
Map<String,String> vars = Map.of("data", json); // "{\"id\":1}"
Defensive patterns

Strategy: validation

Validate before calling

ObjectMapper m = new ObjectMapper();
boolean isAwsJson = false;
try { m.readTree(value); isAwsJson = true; } catch (Exception ignored) {}
if (!isAwsJson) throw new IllegalArgumentException("data must be a valid JSON-encoded string");
vars.put("data", m.writeValueAsString(payload)); // build with the mapper

Type guard

// JS
const isAwsJson = (s) => { try { JSON.parse(s); return true; } catch { return false; } };

Try / catch

catch (CoercingParseValueException e) { /* field-level GraphQL error: surface the message, it echoes the offending string */ }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Related errors


AI-assisted analysis of floci-io/floci@62ff490619 (2026-08-14). Data as JSON: /api/errors/dcafe1d37b5eacfc. Report an issue: GitHub.