{"record":{"id":"5d5dc876a5eb19fe","repo":"apache/cordova-android","slug":"relative-uris-are-not-supported","errorCode":null,"errorMessage":"Relative URIs are not supported.","messagePattern":"Relative URIs are not supported\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"framework/src/org/apache/cordova/CordovaResourceApi.java","lineNumber":477,"sourceCode":"        }\n        String dataPartAsString = uriAsString.substring(commaPos + 1);\n        byte[] data;\n        if (base64) {\n            data = Base64.decode(dataPartAsString, Base64.DEFAULT);\n        } else {\n            try {\n                data = dataPartAsString.getBytes(\"UTF-8\");\n            } catch (UnsupportedEncodingException e) {\n                data = dataPartAsString.getBytes();\n            }\n        }\n        InputStream inputStream = new ByteArrayInputStream(data);\n        return new OpenForReadResult(uri, inputStream, contentType, data.length, null);\n    }\n\n    private static void assertNonRelative(Uri uri) {\n        if (!uri.isAbsolute()) {\n            throw new IllegalArgumentException(\"Relative URIs are not supported.\");\n        }\n    }\n\n    public static final class OpenForReadResult {\n        public final Uri uri;\n        public final InputStream inputStream;\n        public final String mimeType;\n        public final long length;\n        public final AssetFileDescriptor assetFd;\n\n        public OpenForReadResult(Uri uri, InputStream inputStream, String mimeType, long length, AssetFileDescriptor assetFd) {\n            this.uri = uri;\n            this.inputStream = inputStream;\n            this.mimeType = mimeType;\n            this.length = length;\n            this.assetFd = assetFd;\n        }\n    }","sourceCodeStart":459,"sourceCodeEnd":495,"githubUrl":"https://github.com/apache/cordova-android/blob/7c1e190064e349ffa4bbc6ac37b77cd773e4dbd3/framework/src/org/apache/cordova/CordovaResourceApi.java#L459-L495","documentation":"assertNonRelative rejects any Uri without a scheme (uri.isAbsolute() == false) with IllegalArgumentException. CordovaResourceApi methods (openForRead, openOutputStream, processUri) need an absolute URI because they dispatch on the scheme; relative references like 'img/foo.png' are meaningless until resolved against a base, and the API deliberately does not guess one.","triggerScenarios":"Passing Uri.parse(\"www/file.txt\"), \"img/logo.png\", or a protocol-relative \"//example.com/x\" to openForRead/openOutputStream; also Uris recovered from JS as plain paths without a base; processUri called on an unresolved link from shouldInterceptRequest.","commonSituations":"Plugin receives a path string from JavaScript (document-relative) and forwards it straight to the resource API; migrating code from File-relative operations; parsing a href out of HTML and forgetting it can be relative.","solutions":["Resolve against an explicit absolute base before the call: Uri.parse(\"file:///android_asset/www/\").buildUpon().appendPath(\"img/logo.png\").build(), or resolve within a remapUri() implementation using the WebView's base URL","On the JS side always hand absolute URLs (or use toPluginUri from native) when crossing into native code"],"exampleFix":"// before\nresourceApi.openForRead(Uri.parse(\"img/logo.png\")); // no scheme -> IllegalArgumentException\n\n// after\nUri base = Uri.parse(\"file:///android_asset/www/index.html\");\nUri abs = base.resolve(Uri.parse(\"img/logo.png\"));\nresourceApi.openForRead(abs);","handlingStrategy":"type-guard","validationCode":"// resolve relative references against a known absolute base before calling\nUri base = Uri.parse(\"file:///android_asset/www/\");\nUri abs = uri.isAbsolute() ? uri : base.resolve(uri);\nOpenForReadResult r = resourceApi.openForRead(abs);","typeGuard":"static boolean isAbsoluteUri(Uri uri) {\n    return uri != null && uri.isAbsolute(); // scheme present, e.g. file:// https:// content:// data:\n}","tryCatchPattern":"try {\n    resourceApi.openForRead(uri);\n} catch (IllegalArgumentException e) {\n    if (\"Relative URIs are not supported.\".equals(e.getMessage())) {\n        // resolve against a base URI and retry\n    }\n}","preventionTips":["Send absolute URLs from JS to native","Resolve links inside remapUri() using the WebView base URL","Reject/normalize scheme-less strings at the plugin boundary"],"tags":["cordova","cordova-android","java","uri","resource-api"],"backgroundTag":"relative-uri-not-allowed","analyzedSha":"7c1e190064e349ffa4bbc6ac37b77cd773e4dbd3","analyzedAt":"2026-08-22T04:57:58.868Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}