karatelabs/karate · error · RuntimeException

Failed to write file:

Error message

Failed to write file: 

What it means

karate.write() wraps java.nio.Files.write in a try/catch; when the actual file write fails for any reason (bad path, permissions, disk full, invalid characters), the exception is rethrown as a RuntimeException naming the absolute target path, with the original cause attached.

Solutions

  1. Read the chained cause ('Caused by') for the real OS error and fix accordingly
  2. Sanitize the path argument: strip/replace illegal characters and avoid directory separators
  3. Ensure the output directory exists and is writable (check karate.outputDir / target/karate-reports permissions)
  4. Use a simple relative filename so Karate resolves it under the configured output dir.

Example fix

// before
karate.write(data, url + '.json'); // url contains ':' and '/'
// after
var name = url.replace(/[^a-zA-Z0-9._-]/g, '_');
karate.write(data, name + '.json');
Defensive patterns

Strategy: try-catch

Validate before calling

// JS
var safe = path.replace(/[^a-zA-Z0-9._-]/g, '_');
karate.write(value, safe);

Type guard

function isSafeFileName(p) { return /^[a-zA-Z0-9._-]+$/.test(p); }

Try / catch

try { karate.write(value, path); } catch (e) { karate.warn('file write failed: ' + e + ' cause=' + e.cause); }

Prevention

When it happens

Trigger: Writing to a path containing illegal filename characters (e.g. ':' or '/' derived from a URL), the output directory not existing and not being creatable, no write permission on target/karate-reports, or disk full.

Common situations: Deriving the filename from an API response or URL with characters invalid on the OS; CI containers with read-only workspaces; very long paths on Windows; report directory wiped by a concurrent build.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/core/KarateJs.java:1171

            // Create the full path
            File file = new File(outputDir, path);

            // Ensure parent directories exist
            File parent = file.getParentFile();
            if (parent != null && !parent.exists()) {
                parent.mkdirs();
            }

            // Convert value to bytes
            byte[] bytes = KarateJsUtils.convertToBytes(value);

            // Write to file
            try {
                Files.write(file.toPath(), bytes);
                logger.debug("wrote {} bytes to: {}", bytes.length, file.getAbsolutePath());
                return file;
            } catch (Exception e) {
                throw new RuntimeException("Failed to write file: " + file.getAbsolutePath(), e);
            }
        };
    }

    /**
     * JS-side access to the active browser driver, initialising it lazily from
     * {@code configure driver = { ... }} on first read — the JS equivalent of the
     * {@code * driver ...} step. Useful when driver lifecycle is orchestrated inside
     * a JS function (e.g. iterating over a list of browser configs in a grid run),
     * where Gherkin steps aren't reachable per iteration. Returns the same instance
     * exposed via the {@code driver} root binding; after {@code driver.quit()} a
     * subsequent read re-inits cleanly via {@link ScenarioRuntime#getDriver()}.
     */
    private io.karatelabs.driver.Driver getDriverLazy() {
        ScenarioRuntime rt = getRuntime();
        if (rt == null) {
            throw new RuntimeException("karate.driver can only be read within a scenario");
        }

View on GitHub (pinned to a22eb90246)