{"record":{"id":"7d72aa4503ac810c","repo":"karatelabs/karate","slug":"failed-to-read-text-from-path","errorCode":null,"errorMessage":"Failed to read text from: {path}","messagePattern":"Failed to read text from: (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/common/PathResource.java","lineNumber":225,"sourceCode":"            return Files.newInputStream(path);\n        } catch (Exception e) {\n            throw new RuntimeException(\"Failed to open stream for: \" + path, e);\n        }\n    }\n\n    @Override\n    public String getRelativePath() {\n        return relativePath;\n    }\n\n    @Override\n    public String getText() {\n        if (text == null) {\n            try {\n                bytes = Files.readAllBytes(path);\n                text = FileUtils.toString(bytes);\n            } catch (Exception e) {\n                throw new RuntimeException(\"Failed to read text from: \" + path, e);\n            }\n        }\n        return text;\n    }\n\n    @Override\n    public String getLine(int index) {\n        if (lines == null) {\n            lines = getText().split(\"\\\\r?\\\\n\");\n        }\n        return lines[index];\n    }\n\n    @Override\n    public long getLastModified() {\n        try {\n            return Files.getLastModifiedTime(path).toMillis();\n        } catch (Exception e) {","sourceCodeStart":207,"sourceCodeEnd":243,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/common/PathResource.java#L207-L243","documentation":"PathResource.getText() lazily reads the file's bytes (Files.readAllBytes) and decodes them to a String, caching the result. Any I/O failure during the read — file missing, unreadable, is a directory, or too large to hold in memory — is wrapped in this RuntimeException naming the path.","triggerScenarios":"Reading a resource whose file was deleted or moved after PathResource creation; no read permission; path refers to a directory; attempting to read a huge binary as text causing OOM wrapped as a read error; file on an unavailable network drive.","commonSituations":"Tests reading config/fixtures from a relative path that differs between local and CI working directories; fixtures removed by a clean step running concurrently; expecting text from a directory path by mistake.","solutions":["Confirm the path in the message exists and is a readable file before calling getText","Run from the expected working directory or use absolute/classpath paths for fixtures","Check file permissions for the executing user","For large or binary files, stream via getStream() instead of loading all text"],"exampleFix":"// before\nString text = Resource.path(\"config/missing.json\").getText();\n// after\nResource r = Resource.path(\"classpath:config/app.json\");\nif (r.exists()) {\n    String text = r.getText();\n}","handlingStrategy":"validation","validationCode":"// Java: pre-check existence and readability before getText\nPath p = Paths.get(\"config/app.json\");\nif (!Files.isRegularFile(p) || !Files.isReadable(p)) {\n    throw new IllegalStateException(\"fixture missing or unreadable: \" + p);\n}","typeGuard":null,"tryCatchPattern":"try {\n    String text = pathResource.getText();\n} catch (RuntimeException e) {\n    if (e.getMessage().startsWith(\"Failed to read text from:\")) {\n        logger.error(\"read failed for {} cause: {}\", e.getMessage(), e.getCause());\n    }\n}","preventionTips":["Use classpath: prefixes for fixtures to be independent of the working directory","Call exists() before getText when the file may not have been produced yet","Stream large/binary files with getStream() instead of reading all text","Keep fixtures out of clean-plugin targets in CI"],"tags":["io","file-read","resource"],"backgroundTag":"file-read-failed","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"}