karatelabs/karate · warning

[callSingle] disk cache read failed

Error message

[callSingle] disk cache read failed: {} - {}

What it means

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.

Solutions

  1. Delete the corrupt cache file (path is printed in the log) and re-run; callSingle will re-execute and rewrite it.
  2. Clear the whole callSingle cache directory if multiple entries may be stale.
  3. Do not hand-edit cache files; regenerate them by running the feature once.
  4. If frequent truncation occurs, ensure the process is not being killed mid-write (graceful shutdown, adequate disk space).

Example fix

// before
$ cat target/karate.callSingle/cache-abc.json  // truncated, hand-edited
// after
$ rm target/karate.callSingle/cache-abc.json && mvn test
Defensive patterns

Strategy: fallback

Validate before calling

// pre-flight: delete corrupt cache entries
Files.list(cacheDir).filter(p -> !isParseable(p)).forEach(p -> p.toFile().delete());

Try / catch

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 */ }

Prevention

When it happens

Trigger: A callSingle cache file exists and is fresh, but JSON/parse of its contents throws when read in ScenarioRuntime's callSingle disk-cache path.

Common situations: 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.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/e988c66941a4395b. Report an issue: GitHub.

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/core/ScenarioRuntime.java:747

            // Check disk cache if configured
            if (cacheMinutes > 0) {
                String cleanedName = StringUtils.toIdString(path);
                cacheFile = new File(cacheDir, cleanedName + ".txt");
                long staleThreshold = System.currentTimeMillis() - (cacheMinutes * 60L * 1000L);

                if (cacheFile.exists()) {
                    long lastModified = cacheFile.lastModified();
                    if (lastModified > staleThreshold) {
                        try {
                            String json = Files.readString(cacheFile.toPath());
                            result = Json.parseLenient(json);
                            logger.info("[callSingle] disk cache hit: {}", cacheFile);
                        } catch (Exception e) {
                            // a truncated or hand-edited file fails to parse, which is a
                            // RuntimeException, not an IOException — falling back to executing
                            // the feature beats failing every scenario until it is deleted
                            result = null;
                            logger.warn("[callSingle] disk cache read failed: {} - {}", cacheFile, e.getMessage());
                        }
                    } else {
                        logger.info("[callSingle] disk cache stale: {} (modified {}ms ago, threshold {}min)",
                                cacheFile, System.currentTimeMillis() - lastModified, cacheMinutes);
                    }
                } else {
                    logger.debug("[callSingle] disk cache miss, will create: {}", cacheFile);
                }
            }

            // Execute if not found in disk cache
            if (result == null) {
                logger.info("[callSingle] >> executing: {}", path);
                long startExec = System.currentTimeMillis();

                try {
                    result = executeCallSingleInternal(path, arg);
                } catch (Exception e) {

View on GitHub (pinned to a22eb90246)