{"record":{"id":"34f17d72a8e88f9a","repo":"karatelabs/karate","slug":"readbytes-requires-a-path-argument","errorCode":null,"errorMessage":"readBytes() requires a path argument","messagePattern":"readBytes\\(\\) requires a path argument","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"karate-core/src/main/java/io/karatelabs/markup/MarkupContext.java","lineNumber":133,"sourceCode":"\n    /**\n     * Default implementation of jsGet that exposes context methods to JavaScript.\n     * Implementations can override to add more properties/methods.\n     */\n    @Override\n    default Object jsGet(String key) {\n        return switch (key) {\n            case \"template\" -> getTemplateName();\n            case \"caller\" -> getCallerTemplateName();\n            case \"read\" -> (JavaInvokable) args -> {\n                if (args.length == 0 || args[0] == null) {\n                    throw new RuntimeException(\"read() requires a path argument\");\n                }\n                return read(args[0].toString());\n            };\n            case \"readBytes\" -> (JavaInvokable) args -> {\n                if (args.length == 0 || args[0] == null) {\n                    throw new RuntimeException(\"readBytes() requires a path argument\");\n                }\n                return readBytes(args[0].toString());\n            };\n            case \"toJson\" -> (JavaInvokable) args -> {\n                // null IS a valid JSON-able value (`null`), so only the\n                // missing-arg case errors here.\n                if (args.length == 0) throw new RuntimeException(\"toJson() requires an object argument\");\n                return toJson(args[0]);\n            };\n            case \"fromJson\" -> (JavaInvokable) args -> {\n                if (args.length == 0 || args[0] == null) {\n                    throw new RuntimeException(\"fromJson() requires a JSON string argument\");\n                }\n                return fromJson(args[0].toString());\n            };\n            // context.get(name, default?) for optional fragment params.\n            // Walks the current eval scope (`_` map first, then wrapped\n            // Thymeleaf scope). Returns the bound non-null value if found,","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/markup/MarkupContext.java#L115-L151","documentation":"MarkupContext exposes a JS-callable `readBytes(path)` function that returns the raw bytes of a resource at the given path. When invoked with no arguments or a null first argument, the JavaInvokable wrapper throws this RuntimeException, since there is no path to read.","triggerScenarios":"Calling `context.readBytes()` or `context.readBytes(null)` in template script — argument omitted or bound to a null model value.","commonSituations":"Dynamic byte-asset paths (images, files) that resolve to null when the model key is absent; missing argument after refactor; copying the `read()` call pattern and leaving the argument empty.","solutions":["Pass a non-null path string: `context.readBytes('/assets/logo.png')`.","Guard dynamic paths before calling: `path != null ? context.readBytes(path) : fallbackBytes`.","Verify the model variable feeding the path is populated in the render context.","Distinguish 'no argument' from 'file not found' — this error is about the missing argument; a valid path that doesn't exist fails later in readBytes with a different error."],"exampleFix":"// before\nvar bytes = context.readBytes(assetPath);\n\n// after\nvar bytes = assetPath != null ? context.readBytes(assetPath) : null;","handlingStrategy":"validation","validationCode":"function safeReadBytes(ctx, path) {\n  if (path == null || path === '') return null;\n  return ctx.readBytes(path);\n}","typeGuard":"function hasPath(a) { return a != null && typeof a === 'string' && a.length > 0; }\n// usage: if (hasPath(p)) context.readBytes(p);","tryCatchPattern":"try {\n  var bytes = context.readBytes(p);\n} catch (e) {\n  if (e.message === 'readBytes() requires a path argument') {\n    bytes = null;\n  } else { throw e; }\n}","preventionTips":["Pass an explicit non-null path to context.readBytes","Guard dynamic asset paths before calling","Ensure the model attribute holding the path is bound at render time","Don't conflate this missing-argument error with file-not-found"],"tags":["markup","javascript-binding","missing-argument","template"],"backgroundTag":"missing-required-argument","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"}