{"record":{"id":"d455e466e1006717","repo":"apple/pkl","slug":"rewrite-rule-must-start-with-http-or-https","errorCode":null,"errorMessage":"Rewrite rule must start with 'http://' or 'https://', but was '%s'","messagePattern":"Rewrite rule must start with 'http://' or 'https://', but was '(.+?)'","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pkl-core/src/main/java/org/pkl/core/util/IoUtils.java","lineNumber":900,"sourceCode":"\n  private static int getExclamationMarkIndex(String jarUri) {\n    var index = jarUri.indexOf('!');\n    if (index == -1) {\n      throw new IllegalArgumentException(\"Invalid `jar:` URI (missing `!`): \" + jarUri);\n    }\n    return index;\n  }\n\n  public static void validateFileUri(URI uri) throws URISyntaxException {\n    if (!uri.getSchemeSpecificPart().startsWith(\"/\")) {\n      throw new URISyntaxException(uri.toString(), ErrorMessages.create(\"invalidOpaqueFileUri\"));\n    }\n  }\n\n  public static void validateRewriteRule(URI rewrite) {\n    if (!Objects.equals(rewrite.getScheme(), \"http\")\n        && !Objects.equals(rewrite.getScheme(), \"https\")) {\n      throw new IllegalArgumentException(\n          \"Rewrite rule must start with 'http://' or 'https://', but was '%s'\".formatted(rewrite));\n    }\n\n    if (!rewrite.toString().endsWith(\"/\")) {\n      throw new IllegalArgumentException(\n          \"Rewrite rule must end with '/', but was '%s'\".formatted(rewrite));\n    }\n  }\n\n  private static boolean isReservedHeaderName(String headerName) {\n    var normalizedHeader = headerName.toLowerCase(Locale.ROOT);\n    for (var reservedHeader : reservedHeaderNames) {\n      if (normalizedHeader.equals(reservedHeader)) {\n        return true;\n      }\n    }\n    return false;\n  }","sourceCodeStart":882,"sourceCodeEnd":918,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/util/IoUtils.java#L882-L918","documentation":"validateRewriteRule checks URI-rewrite rules used to redirect remote module fetches. A rule must be an http:// or https:// URI; this IllegalArgumentException is thrown for rules with any other scheme (file:, package:, relative, etc.).","triggerScenarios":"Passing a rewrite rule URI with a non-http(s) scheme to validateRewriteRule, e.g. via --rewrite-settings or a rewrite block in PklProject configuration pointing at file: or a relative URI.","commonSituations":"Misconfiguring module rewrites by pointing them at a local directory instead of an HTTP mirror, or forgetting the scheme in the config value.","solutions":["Use an http:// or https:// base URI for the rewrite target","Fix the scheme in the rewrite configuration entry","Remove the rule if a local override is not supported"],"exampleFix":"// before\nrewrite { [\"example.com/mypackage/\"] = \"file:///local/mypackage/\" }\n// after\nrewrite { [\"example.com/mypackage/\"] = \"https://localhost:8080/mypackage/\" }","handlingStrategy":"validation","validationCode":"URI r = URI.create(ruleStr);\nif (!r.getScheme().equals(\"http\") && !r.getScheme().equals(\"https\")) throw new IllegalArgumentException(\"rewrite rule must be http(s)\");","typeGuard":"function isHttpUri(u) { return u != null && (u.getScheme().equals(\"http\") || u.getScheme().equals(\"https\")); }","tryCatchPattern":"try { IoUtils.validateRewriteRule(rewrite) } catch (IllegalArgumentException e) { /* report bad scheme in rewrite config */ }","preventionTips":["Only use http(s) mirrors as rewrite targets","Validate rewrite settings at config-load time","Document that file-based overrides are not valid rewrite rules"],"tags":["uri","config","rewrite"],"backgroundTag":"invalid-config-value","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}