{"record":{"id":"e9e5d6d8c6f2f6e7","repo":"MuntashirAkon/AppManager","slug":"ioexception-remoteexception-remotefile","errorCode":null,"errorMessage":"IOException(remoteException)","messagePattern":"IOException\\(remoteException\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"libcore/io/src/main/java/io/github/muntashirakon/io/RemoteFile.java","lineNumber":58,"sourceCode":"\n    @NonNull\n    @Override\n    public RemoteFile getChildFile(String name) {\n        return new RemoteFile(fs, getPath(), name);\n    }\n\n    @Override\n    protected RemoteFile[] createArray(int n) {\n        return new RemoteFile[n];\n    }\n\n    @Override\n    @NonNull\n    public String getCanonicalPath() throws IOException {\n        try {\n            return fs.getCanonicalPath(getPath()).tryAndGet();\n        } catch (RemoteException e) {\n            throw new IOException(e);\n        }\n    }\n\n    private boolean checkAccess(int access) {\n        try {\n            return fs.checkAccess(getPath(), access);\n        } catch (RemoteException e) {\n            return false;\n        }\n    }\n\n    @Override\n    public boolean canRead() {\n        return checkAccess(OsConstants.R_OK);\n    }\n\n    @Override\n    public boolean canWrite() {","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/libcore/io/src/main/java/io/github/muntashirakon/io/RemoteFile.java#L40-L76","documentation":"RemoteFile.getCanonicalPath() wraps the Binder RemoteException thrown by the remote IServiceProvider's getCanonicalPath() call into an IOException. This is an IPC failure, not a filesystem error: the remote process was unavailable, crashed, or the transaction failed.","triggerScenarios":"Calling getCanonicalPath() when the remote service process is dead, the Binder transaction fails, or the reply could not be read (TransactionTooLargeException, DeadObjectException).","commonSituations":"The provider/host app was killed in the background while a RemoteFile operation was in flight; service disconnected between binding and the call; oversized parceled replies on old Android versions.","solutions":["Verify/rebind the remote service (recreate the RemoteFile with a live service instance) and retry.","Catch IOException around RemoteFile calls and re-acquire the service before retrying once.","Check for DeadObjectException semantics in logs to distinguish process death from path errors.","Add linkToDeath/reconnect logic on the service binding so stale services are refreshed before calls."],"exampleFix":"// before\nString canonical = remoteFile.getCanonicalPath();\n// after\nString canonical;\ntry {\n    canonical = remoteFile.getCanonicalPath();\n} catch (IOException e) {\n    service = rebindService();\n    canonical = new RemoteFile(service, remoteFile.getPath()).getCanonicalPath();\n}","handlingStrategy":"retry","validationCode":"if (service == null || !service.asBinder().pingBinder()) {\n    service = rebindService();\n}","typeGuard":null,"tryCatchPattern":"try {\n    return remoteFile.getCanonicalPath();\n} catch (IOException e) {\n    if (e.getCause() instanceof RemoteException) {\n        rebindService();\n        return remoteFile.getCanonicalPath();\n    }\n    throw e;\n}","preventionTips":["Ping the binder before IPC-heavy batches.","Register a DeathRecipient to refresh stale service instances.","Retry once on RemoteException-derived IOExceptions before surfacing."],"tags":["ipc","binder","remote-exception","android"],"backgroundTag":"ipc-call-failed","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}