floci-io/floci · error · CoercingParseValueException

Invalid AWSPhone: {}

Error message

Invalid AWSPhone: {}

What it means

Thrown by the AWSPhone scalar's parseValue when the string does not match the E.164 pattern ^\+[1-9]\d{1,14}$ — a plus sign, a non-zero-leading country code, and 1–14 further digits, with nothing else. The scalar enforces canonical E.164 format.

Source

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

            }
        })
        .build();

    private static final Pattern PHONE_PATTERN = Pattern.compile("^\\+[1-9]\\d{1,14}$");

    public static final GraphQLScalarType AWS_PHONE = GraphQLScalarType.newScalar()
        .name("AWSPhone")
        .description("An E.164 phone number")
        .coercing(new Coercing<String, String>() {
            @Override
            public String serialize(Object dataFetcherResult) {
                return dataFetcherResult != null ? dataFetcherResult.toString() : null;
            }
            @Override
            public String parseValue(Object input) {
                String str = input.toString();
                if (!PHONE_PATTERN.matcher(str).matches())
                    throw new CoercingParseValueException("Invalid AWSPhone: " + str);
                return str;
            }
            @Override
            public String parseLiteral(Object input) {
                if (!(input instanceof StringValue sv)) return null;
                return parseValue(sv.getValue());
            }
        })
        .build();

    private static final Pattern IPV4_PATTERN = Pattern.compile(
        "^(?:(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$");
    private static final Pattern IPV6_PATTERN = Pattern.compile(
        "^[0-9a-fA-F:]+$");

    public static final GraphQLScalarType AWS_IP_ADDRESS = GraphQLScalarType.newScalar()
        .name("AWSIPAddress")
        .description("An IPv4 or IPv6 address")

View on GitHub (pinned to 62ff490619)

Solutions

  1. Canonicalize to E.164 before sending: strip everything except digits, prepend country code and + (libraries like libphonenumber do this reliably)
  2. Reject display-formatted strings client-side with your own validation
  3. Do not append extensions (x99); store them in a separate field
  4. Unit-test canonicalization with typical input formats

Example fix

// before
String phone = "+1 (555) 123-4567"; // punctuation -> throws

// after
String phone = "+15551234567"; // digits only with country code
Defensive patterns

Strategy: validation

Validate before calling

static String toE164(String raw, String defaultRegion) {
    var p = com.google.i18n.phonenumbers.PhoneNumberUtil.getInstance().parse(raw, defaultRegion);
    return com.google.i18n.phonenumbers.PhoneNumberUtil.getInstance().format(p, PhoneNumberFormat.E164);
} // or: "+" + raw.replaceAll("\\D", "")

Type guard

const isAwsPhone = (s: string): boolean => /^\+[1-9]\d{1,14}$/.test(s);

Try / catch

catch (CoercingParseValueException e) { // input not canonical: run E164 normalization, then retry }

Prevention

When it happens

Trigger: A GraphQL request sends "555-123-4567" (no +country code), "+1 (555) 123-4567" (spaces/parens/dashes), "0123456789" (leading zero after + is rejected), or "+1" (no subscriber digits) as an AWSPhone variable.

Common situations: Saving as-typed user input from phone widgets that format for display (dashes, spaces, parentheses); national numbers without country code; extensions appended like "+14155551234x99"; leading zeros or shorter-than-expected numbers in test data.

Related errors


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