{"record":{"id":"d180ace5d51d5868","repo":"koral--/android-gif-drawable","slug":"could-not-open-assetfiledescriptor-for-uri","errorCode":null,"errorMessage":"Could not open AssetFileDescriptor for <uri>","messagePattern":"Could not open AssetFileDescriptor for <uri>","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"android-gif-drawable/src/main/java/pl/droidsonroids/gif/GifInfoHandle.java","lineNumber":104,"sourceCode":"\tprivate static int getNativeFileDescriptor(FileDescriptor fileDescriptor, boolean closeOriginalDescriptor) throws GifIOException, ErrnoException {\n\t\ttry {\n\t\t\tfinal int nativeFileDescriptor = createTempNativeFileDescriptor();\n\t\t\tOs.dup2(fileDescriptor, nativeFileDescriptor);\n\t\t\treturn nativeFileDescriptor;\n\t\t} finally {\n\t\t\tif (closeOriginalDescriptor) {\n\t\t\t\tOs.close(fileDescriptor);\n\t\t\t}\n\t\t}\n\t}\n\n\tstatic GifInfoHandle openUri(ContentResolver resolver, Uri uri) throws IOException {\n\t\tif (ContentResolver.SCHEME_FILE.equals(uri.getScheme())) { //workaround for #128\n\t\t\treturn new GifInfoHandle(uri.getPath());\n\t\t}\n\t\tfinal AssetFileDescriptor assetFileDescriptor = resolver.openAssetFileDescriptor(uri, \"r\");\n\t\tif (assetFileDescriptor == null) {\n\t\t\tthrow new IOException(\"Could not open AssetFileDescriptor for \" + uri);\n\t\t}\n\t\treturn new GifInfoHandle(assetFileDescriptor);\n\t}\n\n\tstatic native long openNativeFileDescriptor(int fd, long offset) throws GifIOException;\n\n\tstatic native int extractNativeFileDescriptor(FileDescriptor fileDescriptor, boolean closeOriginalDescriptor) throws GifIOException;\n\n\tstatic native int createTempNativeFileDescriptor() throws GifIOException;\n\n\tstatic native long openByteArray(byte[] bytes) throws GifIOException;\n\n\tstatic native long openDirectByteBuffer(ByteBuffer buffer) throws GifIOException;\n\n\tstatic native long openStream(InputStream stream) throws GifIOException;\n\n\tstatic native long openFile(String filePath) throws GifIOException;\n","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/koral--/android-gif-drawable/blob/26ff795f78b7fe8bbaf375a947b2bda95fc58e3d/android-gif-drawable/src/main/java/pl/droidsonroids/gif/GifInfoHandle.java#L86-L122","documentation":"GifInfoHandle.openUri resolves a Uri via ContentResolver.openAssetFileDescriptor(uri, \"r\"). When the resolver returns null (the provider could not open the Uri), an IOException('Could not open AssetFileDescriptor for <uri>') is thrown, embedding the failing Uri in the message.","triggerScenarios":"Calling GifDrawableBuilder.from(resolver, uri) or GifInfoHandle.openUri with a Uri whose content provider returns null, e.g. a content:// Uri for a nonexistent/unavailable resource (non-file scheme).","commonSituations":"Stale content:// URIs (e.g. from a removed gallery entry); provider not exported or permission missing; Uri typo or wrong authority after app reinstall.","solutions":["Verify the Uri is resolvable: check resolver.openAssetFileDescriptor(uri, \"r\") != null or query the provider before loading.","Request and grant the necessary URI permissions (FLAG_GRANT_READ_URI_PERMISSION) for content:// URIs.","Re-fetch the Uri if it came from a picker — the underlying resource may have been deleted.","Wrap the load in try-catch for IOException and fall back to another source."],"exampleFix":"// before\ngifDrawable = new GifDrawableBuilder().from(resolver, staleUri).build();\n// after\nif (resolver.getType(staleUri) != null) {\n    gifDrawable = new GifDrawableBuilder().from(resolver, staleUri).build();\n} else {\n    // re-pick or use fallback source\n}","handlingStrategy":"try-catch","validationCode":"if (resolver.getType(uri) != null) { gifDrawable = new GifDrawableBuilder().from(resolver, uri).build(); }","typeGuard":null,"tryCatchPattern":"try { gifDrawable = new GifDrawableBuilder().from(resolver, uri).build(); } catch (IOException e) { /* Uri unresolvable — re-pick resource or use fallback */ }","preventionTips":["Verify content:// URIs are still valid before use","Grant read permission (FLAG_GRANT_READ_URI_PERMISSION)","Persist taken URIs with takePersistableUriPermission when possible"],"tags":["android","uri","contentresolver","io"],"backgroundTag":"resource-not-found","analyzedSha":"26ff795f78b7fe8bbaf375a947b2bda95fc58e3d","analyzedAt":"2026-09-10T14:37:11.595Z","contentChangedAt":"2026-09-10T14:37:11.595Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}