{"record":{"id":"29cfedb027be1ee0","repo":"karatelabs/karate","slug":"boot-read-file-not-found-path-resolved-to-r-root-is-root-a","errorCode":null,"errorMessage":"boot.read: file not found: ${path} (resolved to ${r}; root is ${root} — a leading '/' anchors the project root, 'file:' is a host path)","messagePattern":"boot\\.read: file not found: (.+?) \\(resolved to (.+?); root is (.+?) — a leading '/' anchors the project root, 'file:' is a host path\\)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"karate-core/src/main/java/io/karatelabs/core/BootBinding.java","lineNumber":187,"sourceCode":"    }\n\n    /**\n     * {@code boot.read('path')} — read a text file, on the one unified rule: a leading {@code /}\n     * anchors THE project root, a bare ref is root-relative, {@code classpath:} is\n     * classloader-first then the {@link #classpath(String)} fallback, and {@code file:} is a host\n     * path. Declare {@code boot.classpath(...)} before reading a {@code classpath:} ref that is\n     * not on the real classpath.\n     */\n    public String read(String path) {\n        if (path == null) throw new IllegalArgumentException(\"boot.read: path is null\");\n        java.nio.file.Path classpathRoot = classpathDir == null || root == null\n                ? root : root.resolve(classpathDir).normalize();\n        try {\n            Resource r = Resource.path(path, root, classpathRoot);\n            if (r.exists()) {\n                return r.getText();\n            }\n            throw new RuntimeException(\"boot.read: file not found: \" + path\n                    + \" (resolved to \" + r + \"; root is \" + root\n                    + \" — a leading '/' anchors the project root, 'file:' is a host path)\");\n        } catch (io.karatelabs.common.ResourceNotFoundException e) {\n            throw new RuntimeException(\"boot.read: file not found: \" + path\n                    + \" (root is \" + root + \" — a leading '/' anchors the project root, \"\n                    + \"'file:' is a host path; declare boot.classpath(dir) to map 'classpath:' refs)\", e);\n        }\n    }\n\n    /** {@code boot.log('...')} — INFO log with [boot] prefix. */\n    public void log(Object msg) {\n        logger.info(\"[boot] {}\", msg == null ? \"null\" : msg.toString());\n    }\n\n    /**\n     * {@code boot.ext('name')} — resolve + construct + register an ext.\n     *\n     * <p>Resolution by name convention: {@code 'openapi'} →","sourceCodeStart":169,"sourceCodeEnd":205,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/core/BootBinding.java#L169-L205","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Read the 'resolved to ... root is ...' part of the message and correct the path so it points at an existing file.","Declare boot.classpath(dir) before reading classpath: refs that live in a project directory rather than on the real classpath.","Use a leading '/' to anchor at the project root explicitly, or 'file:' for an absolute host path.","Verify the file actually exists at the stated location (rename/move may have changed it)."],"exampleFix":"// before\nboot.read('classpath:data/seed.json'); // not on real classpath\n// after\nboot.classpath('src/test/resources');\nboot.read('classpath:data/seed.json');","handlingStrategy":"validation","validationCode":"// before calling boot.read(path)\n// confirm the file exists at the expected project-relative location\nnew java.io.File(\"src/test/resources/data/seed.json\").exists(); // must be true","typeGuard":null,"tryCatchPattern":"try {\n    var text = boot.read(path);\n} catch (RuntimeException e) {\n    // message includes resolved path and root — use it to correct path or classpath mapping\n}","preventionTips":["Declare boot.classpath(dir) before any classpath: reads of project-only resources.","Use a leading '/' to anchor at the project root explicitly.","Verify file existence after renames/moves and in CI working directories."],"tags":["boot","file-not-found","path-resolution"],"backgroundTag":"file-not-found","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}