{"record":{"id":"407cd59dfbd021c2","repo":"floci-io/floci","slug":"invalid-awsipaddress","errorCode":null,"errorMessage":"Invalid AWSIPAddress: {}","messagePattern":"Invalid AWSIPAddress: (.+?)","errorType":"validation","errorClass":"CoercingParseValueException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/github/hectorvent/floci/services/appsync/graphql/scalars/AppSyncScalars.java","lineNumber":257,"sourceCode":"\n    private static final Pattern IPV4_PATTERN = Pattern.compile(\n        \"^(?:(?:25[0-5]|2[0-4]\\\\d|[01]?\\\\d\\\\d?)\\\\.){3}(?:25[0-5]|2[0-4]\\\\d|[01]?\\\\d\\\\d?)$\");\n    private static final Pattern IPV6_PATTERN = Pattern.compile(\n        \"^[0-9a-fA-F:]+$\");\n\n    public static final GraphQLScalarType AWS_IP_ADDRESS = GraphQLScalarType.newScalar()\n        .name(\"AWSIPAddress\")\n        .description(\"An IPv4 or IPv6 address\")\n        .coercing(new Coercing<String, String>() {\n            @Override\n            public String serialize(Object dataFetcherResult) {\n                return dataFetcherResult != null ? dataFetcherResult.toString() : null;\n            }\n            @Override\n            public String parseValue(Object input) {\n                String str = input.toString();\n                if (!IPV4_PATTERN.matcher(str).matches() && !IPV6_PATTERN.matcher(str).matches()) {\n                    throw new CoercingParseValueException(\"Invalid AWSIPAddress: \" + 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_BOOLEAN = GraphQLScalarType.newScalar()\n        .name(\"AWSBoolean\")\n        .description(\"A boolean value\")\n        .coercing(new Coercing<Boolean, Boolean>() {\n            @Override\n            public Boolean serialize(Object dataFetcherResult) {\n                if (dataFetcherResult == null) return null;","sourceCodeStart":239,"sourceCodeEnd":275,"githubUrl":"https://github.com/floci-io/floci/blob/62ff490619e7bd3554597c28c704081b4c15add5/src/main/java/io/github/hectorvent/floci/services/appsync/graphql/scalars/AppSyncScalars.java#L239-L275","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Send the bare address only — strip CIDR prefix length, port, and zone index before submitting","Validate client-side with InetAddress.getByName or InetAddresses.fromString-style checks (catching DNS lookups) or the same regex pair","Trim whitespace from user or config input","Use a String/hostname field for names, AWSIPAddress only for literal addresses"],"exampleFix":"// before\nString ip = cidr.replaceFirst(\"/.*\", \"\"); // ok\nvariables.put(\"ip\", \"10.0.0.0/24\"); // CIDR -> throws\n\n// after\nvariables.put(\"ip\", cidr.replaceFirst(\"/.*\", \"\")); // 10.0.0.0","handlingStrategy":"validation","validationCode":"static boolean validAwsIp(String s) {\n    try { java.net.InetAddress.getByName(s); return s.contains(\":\") || s.split(\"\\\\.\").length == 4; }\n    catch (Exception e) { return false; }\n}\nString bare = raw.trim().replaceFirst(\"/.*$\", \"\").replaceFirst(\":\\\\d+$\", \"\"); // strip CIDR/port","typeGuard":"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);","tryCatchPattern":"catch (CoercingParseValueException e) { // strip CIDR/port/zone, re-validate, retry }","preventionTips":["Send bare addresses only — no /24 suffix, no :port, no %zone","Trim config-sourced values","Use String fields for hostnames, AWSIPAddress only for literal IPs"],"tags":["graphql","appsync","awsipaddress","ipv4","ipv6","validation"],"backgroundTag":null,"analyzedSha":"62ff490619e7bd3554597c28c704081b4c15add5","analyzedAt":"2026-08-14T14:25:23.764Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}