{"record":{"id":"7b839e7faa4af0cd","repo":"nostra13/Android-Universal-Image-Loader","slug":"uri-1-s-doesn-t-have-expected-scheme-2-s","errorCode":null,"errorMessage":"URI [%1$s] doesn't have expected scheme [%2$s]","messagePattern":"URI \\[%1\\$s\\] doesn't have expected scheme \\[%2\\$s\\]","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"library/src/main/java/com/nostra13/universalimageloader/core/download/ImageDownloader.java","lineNumber":85,"sourceCode":"\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn UNKNOWN;\n\t\t}\n\n\t\tprivate boolean belongsTo(String uri) {\n\t\t\treturn uri.toLowerCase(Locale.US).startsWith(uriPrefix);\n\t\t}\n\n\t\t/** Appends scheme to incoming path */\n\t\tpublic String wrap(String path) {\n\t\t\treturn uriPrefix + path;\n\t\t}\n\n\t\t/** Removed scheme part (\"scheme://\") from incoming URI */\n\t\tpublic String crop(String uri) {\n\t\t\tif (!belongsTo(uri)) {\n\t\t\t\tthrow new IllegalArgumentException(String.format(\"URI [%1$s] doesn't have expected scheme [%2$s]\", uri, scheme));\n\t\t\t}\n\t\t\treturn uri.substring(uriPrefix.length());\n\t\t}\n\t}\n}\n","sourceCodeStart":67,"sourceCodeEnd":91,"githubUrl":"https://github.com/nostra13/Android-Universal-Image-Loader/blob/ba33ec64d0daaa881d35852460e78c58d086bc18/library/src/main/java/com/nostra13/universalimageloader/core/download/ImageDownloader.java#L67-L91","documentation":"Scheme.crop() (on the Scheme enum inside ImageDownloader) strips a known prefix like \"http://\" from a URI and throws IllegalArgumentException if the URI doesn't actually start with that scheme's prefix. It is a strict precondition: you must only call crop() on URIs already verified to belong to that scheme (typically via belongsTo() or Scheme.ofUri()). The format embeds both the offending URI and the expected scheme.","triggerScenarios":"Calling Scheme.HTTP.crop(uri) on a URI like \"file:///path\" or \"https://host\" (HTTPS cropped with the HTTP enum); calling crop() before checking belongsTo(); calling crop(\"\"+id) where the stored value never had the scheme appended (forgetting wrap() on the same data path).","commonSituations":"Persisting cropped IDs and later re-cropping them a second time; mixed http/https data where the wrong enum constant is used; deserialized URIs whose scheme changed between write and read; defensive-code refactors that moved crop() before the scheme check.","solutions":["Guard crop() with belongsTo() (or match on Scheme.ofUri(uri)) before calling it","Use the correct enum constant for the URI you hold — HTTPS.crop for https:// URIs","Keep data symmetric: only crop values produced by wrap(), and wrap again before displayImage","Normalize URIs to a known scheme at the data boundary (DB/model layer) so crop sites can trust them"],"exampleFix":"// before\nString path = Scheme.HTTP.crop(uri); // throws if uri is https:// or file://\n\n// after\nScheme scheme = Scheme.ofUri(uri);\nif (scheme == Scheme.HTTP) {\n    String path = Scheme.HTTP.crop(uri);\n} else {\n    throw new IllegalArgumentException(\"Unexpected scheme for \" + uri);\n}","handlingStrategy":"validation","validationCode":"String prefix = scheme.wrap(\"\"); // e.g. \"http://\"\nif (uri != null && uri.toLowerCase(Locale.US).startsWith(prefix)) {\n    String path = scheme.crop(uri);\n} else {\n    throw new IllegalArgumentException(\"URI \" + uri + \" is not \" + prefix);\n}","typeGuard":"private static boolean belongsToScheme(String uri, ImageDownloader.Scheme scheme) {\n    return uri != null && uri.toLowerCase(Locale.US).startsWith(scheme.wrap(\"\"));\n}","tryCatchPattern":"try {\n    path = Scheme.HTTP.crop(uri);\n} catch (IllegalArgumentException e) {\n    // URI/expected scheme mismatch: re-detect scheme or reject the record\n    LOG.warn(\"Wrong scheme for {}\", uri);\n    path = uri;\n}","preventionTips":["Always pair crop() with a belongsTo()/ofUri() check in the same expression","Store URIs together with their scheme, or never store cropped forms","Use switch on Scheme.ofUri(uri) instead of assuming one constant","Unit-test crop/wrap round-trips over your persisted data set"],"tags":["universal-image-loader","uri-scheme","precondition","validation"],"backgroundTag":null,"analyzedSha":"ba33ec64d0daaa881d35852460e78c58d086bc18","analyzedAt":"2026-08-14T15:41:15.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}