{"record":{"id":"bd15258efb4023ff","repo":"MuntashirAkon/AppManager","slug":"ioexception-error-msg","errorCode":null,"errorMessage":"IOException(ERROR_MSG)","messagePattern":"IOException\\(ERROR_MSG\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"libcore/io/src/main/java/io/github/muntashirakon/io/FileContainer.java","lineNumber":29,"sourceCode":"\n// Copyright 2022 John \"topjohnwu\" Wu\nclass FileContainer {\n\n    private final static String ERROR_MSG = \"Requested file was not opened!\";\n\n    private int nextHandle = 0;\n    // pid -> handle -> holder\n    private final SparseArray<SparseArray<OpenFile>> files = new SparseArray<>();\n\n    @NonNull\n    synchronized OpenFile get(int handle) throws IOException {\n        int pid = Binder.getCallingPid();\n        SparseArray<OpenFile> pidFiles = files.get(pid);\n        if (pidFiles == null)\n            throw new IOException(ERROR_MSG);\n        OpenFile h = pidFiles.get(handle);\n        if (h == null)\n            throw new IOException(ERROR_MSG);\n        return h;\n    }\n\n    synchronized int put(OpenFile h) {\n        int pid = Binder.getCallingPid();\n        SparseArray<OpenFile> pidFiles = files.get(pid);\n        if (pidFiles == null) {\n            pidFiles = new SparseArray<>();\n            files.put(pid, pidFiles);\n        }\n        int handle = nextHandle++;\n        pidFiles.append(handle, h);\n        return handle;\n    }\n\n    synchronized void remove(int handle) {\n        int pid = Binder.getCallingPid();\n        SparseArray<OpenFile> pidFiles = files.get(pid);","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/libcore/io/src/main/java/io/github/muntashirakon/io/FileContainer.java#L11-L47","documentation":"Same lookup as error 644 but the failure is at the handle level: the calling PID has a handle table, but the requested handle number is not present (pidFiles.get(handle) == null). The handle was closed, never issued to this PID, or is stale.","triggerScenarios":"Calling get() with a handle that was already removed via remove(), a handle issued to a different PID, or an arbitrary/overflowed handle integer.","commonSituations":"Double-close then reuse of a handle; caching handles across binder calls after the file was closed; typos or misaligned index arithmetic when storing handles.","solutions":["Re-open the file to obtain a new handle whenever the old one throws this error.","Track handle lifecycle: never use a handle after calling remove()/close().","Guard remote calls so only handles returned by put() in the same process are passed."],"exampleFix":"// before\nOpenFile f = container.get(oldHandle); // stale\n// after\nOpenFile f = container.get(currentHandle != -1 ? currentHandle : container.put(openNew()));","handlingStrategy":"try-catch","validationCode":"Map<Integer, Boolean> liveHandles = new HashMap<>();\nboolean valid = liveHandles.getOrDefault(handle, false);","typeGuard":null,"tryCatchPattern":"try {\n    return container.get(handle);\n} catch (IOException e) {\n    int fresh = container.put(reopen());\n    return container.get(fresh);\n}","preventionTips":["Drop handles after close/remove","Keep handle bookkeeping in one owner class","Treat every handle as invalid after any IOException from get()"],"tags":["ipc","handle","stale-reference"],"backgroundTag":"resource-not-found","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}