{"record":{"id":"e988c66941a4395b","repo":"karatelabs/karate","slug":"callsingle-disk-cache-read-failed","errorCode":null,"errorMessage":"[callSingle] disk cache read failed: {} - {}","messagePattern":"\\[callSingle\\] disk cache read failed: (.+?) - (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"karate-core/src/main/java/io/karatelabs/core/ScenarioRuntime.java","lineNumber":747,"sourceCode":"            // Check disk cache if configured\n            if (cacheMinutes > 0) {\n                String cleanedName = StringUtils.toIdString(path);\n                cacheFile = new File(cacheDir, cleanedName + \".txt\");\n                long staleThreshold = System.currentTimeMillis() - (cacheMinutes * 60L * 1000L);\n\n                if (cacheFile.exists()) {\n                    long lastModified = cacheFile.lastModified();\n                    if (lastModified > staleThreshold) {\n                        try {\n                            String json = Files.readString(cacheFile.toPath());\n                            result = Json.parseLenient(json);\n                            logger.info(\"[callSingle] disk cache hit: {}\", cacheFile);\n                        } catch (Exception e) {\n                            // a truncated or hand-edited file fails to parse, which is a\n                            // RuntimeException, not an IOException — falling back to executing\n                            // the feature beats failing every scenario until it is deleted\n                            result = null;\n                            logger.warn(\"[callSingle] disk cache read failed: {} - {}\", cacheFile, e.getMessage());\n                        }\n                    } else {\n                        logger.info(\"[callSingle] disk cache stale: {} (modified {}ms ago, threshold {}min)\",\n                                cacheFile, System.currentTimeMillis() - lastModified, cacheMinutes);\n                    }\n                } else {\n                    logger.debug(\"[callSingle] disk cache miss, will create: {}\", cacheFile);\n                }\n            }\n\n            // Execute if not found in disk cache\n            if (result == null) {\n                logger.info(\"[callSingle] >> executing: {}\", path);\n                long startExec = System.currentTimeMillis();\n\n                try {\n                    result = executeCallSingleInternal(path, arg);\n                } catch (Exception e) {","sourceCodeStart":729,"sourceCodeEnd":765,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/core/ScenarioRuntime.java#L729-L765","documentation":"callSingle found an existing disk-cache file for the called feature, but parsing it failed (e.g. the file is truncated, hand-edited, or in an unexpected format — the catch covers RuntimeExceptions, not just IOException). Karate logs a warning, discards the cached value, and re-executes the feature, so the run continues correctly.","triggerScenarios":"A callSingle cache file exists and is fresh, but JSON/parse of its contents throws when read in ScenarioRuntime's callSingle disk-cache path.","commonSituations":"Cache file partially written by a killed JVM; file manually edited to invalid JSON; cache written by a different Karate version with an incompatible format; disk corruption.","solutions":["Delete the corrupt cache file (path is printed in the log) and re-run; callSingle will re-execute and rewrite it.","Clear the whole callSingle cache directory if multiple entries may be stale.","Do not hand-edit cache files; regenerate them by running the feature once.","If frequent truncation occurs, ensure the process is not being killed mid-write (graceful shutdown, adequate disk space)."],"exampleFix":"// before\n$ cat target/karate.callSingle/cache-abc.json  // truncated, hand-edited\n// after\n$ rm target/karate.callSingle/cache-abc.json && mvn test","handlingStrategy":"fallback","validationCode":"// pre-flight: delete corrupt cache entries\nFiles.list(cacheDir).filter(p -> !isParseable(p)).forEach(p -> p.toFile().delete());","typeGuard":null,"tryCatchPattern":"try { result = parse(cacheFile); } catch (Exception e) { result = null; logger.warn(\"[callSingle] disk cache read failed: {} - {}\", cacheFile, e.getMessage()); /* fall back to executing the feature */ }","preventionTips":["Never hand-edit callSingle cache files.","Clear the cache directory after Karate version upgrades.","Ensure clean JVM shutdowns so writes are not truncated."],"tags":["callsingle","disk-cache","json"],"backgroundTag":"json-parse-error","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}