karatelabs/karate · error · RuntimeException

boot.read: file not found

Error message

boot.read: file not found: ${path} (resolved to ${r}; root is ${root} — a leading '/' anchors the project root, 'file:' is a host path)

What it means

boot.read(path) resolved the path against the project root (and any boot.classpath dir) but the resulting Resource did not exist, so a RuntimeException is thrown showing the resolved location and the root, with hints about how '/' anchors the project root and how 'file:' refers to host paths. ResourceNotFoundException during resolution produces the sibling variant, but this form fires when the resolved resource simply isn't there.

Solutions

  1. Read the 'resolved to ... root is ...' part of the message and correct the path so it points at an existing file.
  2. Declare boot.classpath(dir) before reading classpath: refs that live in a project directory rather than on the real classpath.
  3. Use a leading '/' to anchor at the project root explicitly, or 'file:' for an absolute host path.
  4. Verify the file actually exists at the stated location (rename/move may have changed it).

Example fix

// before
boot.read('classpath:data/seed.json'); // not on real classpath
// after
boot.classpath('src/test/resources');
boot.read('classpath:data/seed.json');
Defensive patterns

Strategy: validation

Validate before calling

// before calling boot.read(path)
// confirm the file exists at the expected project-relative location
new java.io.File("src/test/resources/data/seed.json").exists(); // must be true

Try / catch

try {
    var text = boot.read(path);
} catch (RuntimeException e) {
    // message includes resolved path and root — use it to correct path or classpath mapping
}

Prevention

When it happens

Trigger: boot.read('some/missing.txt') where the path resolves under the project root or the boot.classpath dir but no file exists there; wrong leading '/' semantics (path resolved relative to root when the file lives elsewhere).

Common situations: Typo in the file path; file exists in src/test/resources but boot.classpath was never declared or points at the wrong directory; running from a different working directory than expected; file was renamed or deleted.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/core/BootBinding.java:187

    }

    /**
     * {@code boot.read('path')} — read a text file, on the one unified rule: a leading {@code /}
     * anchors THE project root, a bare ref is root-relative, {@code classpath:} is
     * classloader-first then the {@link #classpath(String)} fallback, and {@code file:} is a host
     * path. Declare {@code boot.classpath(...)} before reading a {@code classpath:} ref that is
     * not on the real classpath.
     */
    public String read(String path) {
        if (path == null) throw new IllegalArgumentException("boot.read: path is null");
        java.nio.file.Path classpathRoot = classpathDir == null || root == null
                ? root : root.resolve(classpathDir).normalize();
        try {
            Resource r = Resource.path(path, root, classpathRoot);
            if (r.exists()) {
                return r.getText();
            }
            throw new RuntimeException("boot.read: file not found: " + path
                    + " (resolved to " + r + "; root is " + root
                    + " — a leading '/' anchors the project root, 'file:' is a host path)");
        } catch (io.karatelabs.common.ResourceNotFoundException e) {
            throw new RuntimeException("boot.read: file not found: " + path
                    + " (root is " + root + " — a leading '/' anchors the project root, "
                    + "'file:' is a host path; declare boot.classpath(dir) to map 'classpath:' refs)", e);
        }
    }

    /** {@code boot.log('...')} — INFO log with [boot] prefix. */
    public void log(Object msg) {
        logger.info("[boot] {}", msg == null ? "null" : msg.toString());
    }

    /**
     * {@code boot.ext('name')} — resolve + construct + register an ext.
     *
     * <p>Resolution by name convention: {@code 'openapi'} →

View on GitHub (pinned to a22eb90246)