{"record":{"id":"4c584926c7d935dc","repo":"CarGuo/GSYVideoPlayer","slug":"error-append-cache-cache-file-s-is-completed","errorCode":null,"errorMessage":"Error append cache: cache file %s is completed!","messagePattern":"Error append cache: cache file (.+?) is completed!","errorType":"exception","errorClass":"ProxyCacheException","httpStatus":null,"severity":"error","filePath":"gsyVideoPlayer-proxy_cache/src/main/java/com/danikula/videocache/file/FileCache.java","lineNumber":67,"sourceCode":"        }\n    }\n\n    @Override\n    public synchronized int read(byte[] buffer, long offset, int length) throws ProxyCacheException {\n        try {\n            dataFile.seek(offset);\n            return dataFile.read(buffer, 0, length);\n        } catch (IOException e) {\n            String format = \"Error reading %d bytes with offset %d from file[%d bytes] to buffer[%d bytes]\";\n            throw new ProxyCacheException(String.format(format, length, offset, available(), buffer.length), e);\n        }\n    }\n\n    @Override\n    public synchronized void append(byte[] data, int length) throws ProxyCacheException {\n        try {\n            if (isCompleted()) {\n                throw new ProxyCacheException(\"Error append cache: cache file \" + file + \" is completed!\");\n            }\n            dataFile.seek(available());\n            dataFile.write(data, 0, length);\n        } catch (IOException e) {\n            String format = \"Error writing %d bytes to %s from buffer with size %d\";\n            throw new ProxyCacheException(String.format(format, length, dataFile, data.length), e);\n        }\n    }\n\n    @Override\n    public synchronized void close() throws ProxyCacheException {\n        try {\n            dataFile.close();\n            diskUsage.touch(file);\n        } catch (IOException e) {\n            throw new ProxyCacheException(\"Error closing file \" + file, e);\n        }\n    }","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/CarGuo/GSYVideoPlayer/blob/e5d74d3aa9d7fb1393a879e33ee380f8f41354f1/gsyVideoPlayer-proxy_cache/src/main/java/com/danikula/videocache/file/FileCache.java#L49-L85","documentation":"FileCache.append seeks to end and writes; an IOException during seek/write is formatted as 'Error writing N bytes to <file> from buffer with size M'. Almost always the disk is full or the fd is invalid - the proxy cannot persist downloaded bytes and aborts caching.","triggerScenarios":"Device storage fills while the proxy streams a video into the .download temp file; or the cache directory's volume is unmounted / file deleted mid-write (fd invalid).","commonSituations":"Low-storage budget devices (the classic '16GB with 200MB free' user); cache size cap misconfigured larger than free disk; user clearing storage while streaming; cache dir on adopted/removable storage that flakes.","solutions":["Set a sensible maxCacheSize and register cache eviction so the proxy trims before the disk fills","Check StatFs usable space before starting playback on low-storage profiles and prompt the user","Use app-internal cache dir (auto-managed by Android) instead of arbitrary paths","On the error, clear the proxy cache folder and retry playback without caching"],"exampleFix":"// before\nnew Builder(ctx).maxCacheSize(1024L * 1024 * 1024).build(); // 1GB on a full phone\n\n// after - size to free space, evict aggressively\nlong free = new StatFs(ctx.getCacheDir().getAbsolutePath()).getAvailableBytes();\nlong cap = Math.min(512L * 1024 * 1024, free / 4);\nnew Builder(ctx).maxCacheSize(cap).build();","handlingStrategy":"validation","validationCode":"StatFs stat = new StatFs(cacheDir.getAbsolutePath());\nif (stat.getAvailableBytes() < 50L * 1024 * 1024) {\n    trimCacheOrPromptUser(); // or disable caching this session\n}","typeGuard":null,"tryCatchPattern":"catch (ProxyCacheException e) {\n    if (String.valueOf(e.getMessage()).contains(\"Error writing\")) {\n        // disk full: clear cache and continue without caching\n        clearProxyCache(cacheDir); playDirect(url);\n    } else throw e;\n}","preventionTips":["Register DiskUsage/maxCacheSize eviction sized to real free space","Check free bytes before caching","Degrade to no-cache playback on write failure"],"tags":["disk-full","io","storage","proxy-cache"],"backgroundTag":null,"analyzedSha":"e5d74d3aa9d7fb1393a879e33ee380f8f41354f1","analyzedAt":"2026-08-14T11:56:11.997Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}