floci-io/floci · error · CoercingParseValueException

Invalid AWSIPAddress: {}

Error message

Invalid AWSIPAddress: {}

What it means

Thrown by the AWSIPAddress scalar's parseValue when the string matches neither the IPv4 pattern (dotted quad, each octet 0-255) nor the configured IPv6 pattern. The scalar validates text form, so any extra characters, out-of-range octets, or wrong separator count fail.

Source

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

    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")
        .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 (!IPV4_PATTERN.matcher(str).matches() && !IPV6_PATTERN.matcher(str).matches()) {
                    throw new CoercingParseValueException("Invalid AWSIPAddress: " + 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_BOOLEAN = GraphQLScalarType.newScalar()
        .name("AWSBoolean")
        .description("A boolean value")
        .coercing(new Coercing<Boolean, Boolean>() {
            @Override
            public Boolean serialize(Object dataFetcherResult) {
                if (dataFetcherResult == null) return null;

View on GitHub (pinned to 62ff490619)

Solutions

  1. Send the bare address only — strip CIDR prefix length, port, and zone index before submitting
  2. Validate client-side with InetAddress.getByName or InetAddresses.fromString-style checks (catching DNS lookups) or the same regex pair
  3. Trim whitespace from user or config input
  4. Use a String/hostname field for names, AWSIPAddress only for literal addresses

Example fix

// before
String ip = cidr.replaceFirst("/.*", ""); // ok
variables.put("ip", "10.0.0.0/24"); // CIDR -> throws

// after
variables.put("ip", cidr.replaceFirst("/.*", "")); // 10.0.0.0
Defensive patterns

Strategy: validation

Validate before calling

static boolean validAwsIp(String s) {
    try { java.net.InetAddress.getByName(s); return s.contains(":") || s.split("\\.").length == 4; }
    catch (Exception e) { return false; }
}
String bare = raw.trim().replaceFirst("/.*$", "").replaceFirst(":\\d+$", ""); // strip CIDR/port

Type guard

const isAwsIpAddress = (s: string): boolean => /^((25[0-5]|2[0-4]\d|1?\d?\d)\.){3}(25[0-5]|2[0-4]\d|1?\d?\d)$/.test(s) || /^[0-9a-fA-F:]+$/.test(s);

Try / catch

catch (CoercingParseValueException e) { // strip CIDR/port/zone, re-validate, retry }

Prevention

When it happens

Trigger: A GraphQL request sends "999.1.1.1" (octet > 255), "192.168.1" (only three octets), "192.168.1.1/24" (CIDR suffix included), or "2001:db8::g" (invalid hex) as an AWSIPAddress variable.

Common situations: Appending CIDR notation or port ("10.0.0.1:8080") to what is a bare-address field; frontend inputs not stripping whitespace; hostname strings ("db.internal") placed in an address field; IPv6 with zone index ("fe80::1%eth0") which the configured pattern rejects.

Related errors


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