karatelabs/karate · error · IllegalArgumentException

boot.read: path is null

Error message

boot.read: path is null

What it means

boot.read(path) resolves and reads a file relative to the project root (or the classpath-mapped dir), but a null path cannot be resolved, so an IllegalArgumentException is thrown before any resource lookup. The method expects a non-empty string such as a bare root-relative ref, a classpath: ref, or a file: host path.

Solutions

  1. Pass a concrete non-empty path string, e.g. boot.read('classpath:data/seed.json').
  2. Initialize or default the variable feeding the call before boot.read executes.
  3. Guard the call site: only invoke boot.read when the path value is present.

Example fix

// before
var p = karate.env == 'ci' ? ciPath : null; boot.read(p);
// after
var p = karate.env == 'ci' ? ciPath : 'classpath:default/seed.json';
boot.read(p);
Defensive patterns

Strategy: validation

Validate before calling

// before calling boot.read(path)
if (path == null || path.isBlank()) throw new IllegalArgumentException("boot.read path required");

Prevention

When it happens

Trigger: Calling boot.read(null) directly, or passing a variable/interpolation that evaluates to null (e.g. missing config value) into boot.read.

Common situations: Boot config driven by environment variables or suite properties where the expected key is absent; refactored scripts where a path constant was removed but the call remained.

Related errors


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

Appendix: source

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

    }

    /**
     * The directory declared by {@link #classpath(String)}, root-relative and de-slashed, or
     * {@code null} when the project declared nothing (then the fallback dir IS the root).
     */
    public String getClasspathDir() {
        return classpathDir;
    }

    /**
     * {@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. */

View on GitHub (pinned to a22eb90246)