{"record":{"id":"4214715cbf3a3922","repo":"floci-io/floci","slug":"invalid-awsurl","errorCode":null,"errorMessage":"Invalid AWSURL: {}","messagePattern":"Invalid AWSURL: (.+?)","errorType":"validation","errorClass":"CoercingParseValueException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/github/hectorvent/floci/services/appsync/graphql/scalars/AppSyncScalars.java","lineNumber":203,"sourceCode":"            }\n        })\n        .build();\n\n    public static final GraphQLScalarType AWS_URL = GraphQLScalarType.newScalar()\n        .name(\"AWSURL\")\n        .description(\"A valid URL\")\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                try {\n                    URI.create(str).toURL();\n                } catch (Exception e) {\n                    throw new CoercingParseValueException(\"Invalid AWSURL: \" + 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    private static final Pattern PHONE_PATTERN = Pattern.compile(\"^\\\\+[1-9]\\\\d{1,14}$\");\n\n    public static final GraphQLScalarType AWS_PHONE = GraphQLScalarType.newScalar()\n        .name(\"AWSPhone\")\n        .description(\"An E.164 phone number\")\n        .coercing(new Coercing<String, String>() {\n            @Override","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/floci-io/floci/blob/62ff490619e7bd3554597c28c704081b4c15add5/src/main/java/io/github/hectorvent/floci/services/appsync/graphql/scalars/AppSyncScalars.java#L185-L221","documentation":"Thrown by the AWSURL scalar's parseValue when the string cannot be converted to an absolute URL. The coercion calls URI.create(str).toURL(), which requires a syntactically valid URI with a known protocol handler; relative URLs, missing schemes, or malformed URIs throw and produce this error.","triggerScenarios":"A GraphQL request sends \"example.com/path\" (no scheme), \"http//example.com\" (malformed), \"my app://x\" (illegal space), or a relative path \"/callback\" as an AWSURL variable.","commonSituations":"Storing user-entered links without requiring the https:// prefix; concatenating a base URL and path but forgetting the scheme; custom app schemes with invalid characters; whitespace or unicode sneaking into the URL; config values intended to be relative paths placed in URL fields.","solutions":["Always include the scheme: https://example.com/path","Normalize user input: if (!url.matches(\"^https?://.*\")) url = \"https://\" + url; then trim","Validate client-side with new URI(url).toURL() in a try-catch before sending","For relative paths, store them in a plain String field, not AWSURL"],"exampleFix":"// before\nString url = \"example.com/assets/logo.png\"; // no scheme -> throws\n\n// after\nString url = \"https://example.com/assets/logo.png\";","handlingStrategy":"validation","validationCode":"static String normalizeUrl(String raw) {\n    String u = raw.trim();\n    if (!u.matches(\"(?i)^[a-z][a-z0-9+.-]*:.*\")) u = \"https://\" + u;\n    URI.create(u).toURL(); // throws early with a clearer stack\n    return u;\n}","typeGuard":"const isAwsUrl = (s: string): boolean => { try { new URL(s.trim()); return true; } catch { return false; } };","tryCatchPattern":"catch (CoercingParseValueException e) { // ask user for full URL including scheme; auto-prepend https:// then retry }","preventionTips":["Require scheme in URL inputs (UI hint: 'https://…')","Strip whitespace before sending","Never store relative paths in AWSURL fields — use String"],"tags":["graphql","appsync","awsurl","uri","validation"],"backgroundTag":null,"analyzedSha":"62ff490619e7bd3554597c28c704081b4c15add5","analyzedAt":"2026-08-14T14:25:23.764Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}