karatelabs/karate · error · RuntimeException
toJson() requires an object argument
Error message
toJson() requires an object argument
What it means
MarkupContext exposes a JS-callable `toJson(value)` that serializes a value to a JSON string. Null is considered a valid JSON-able value (serializes as `null`), so the only case rejected is calling `toJson()` with zero arguments, which throws this RuntimeException.
Solutions
- Pass the value explicitly, even null: `context.toJson(null)` produces the string 'null'.
- If the data variable may be absent, pass a fallback: `context.toJson(data ?: {})`.
- Check that the intended model key is actually bound in the render scope.
- Remember toJson accepts any object including maps/lists — the error only fires for a missing argument, not a bad type.
Example fix
// before
<script th:inline="text">var cfg = ${context.toJson()};</script>
// after
<script th:inline="text">var cfg = ${context.toJson(config)};</script> Defensive patterns
Strategy: validation
Validate before calling
function safeToJson(ctx, v) {
return ctx.toJson(v === undefined ? null : v);
} Type guard
function isProvided(v) { return typeof v !== 'undefined'; }
// usage: if (!isProvided(v)) v = null; then context.toJson(v) Try / catch
try {
var json = context.toJson(v);
} catch (e) {
if (e.message === 'toJson() requires an object argument') {
json = 'null';
} else { throw e; }
} Prevention
- toJson(null) is valid — pass null explicitly rather than omitting the argument
- Default missing data with `data ?: {}` before serializing
- Confirm the model variable exists before inlining JSON in scripts
- Remember only the zero-argument case errors; any type is accepted
When it happens
Trigger: Calling `context.toJson()` with no arguments in template script — e.g. `th:text="${context.toJson()}"` or building an inline JSON payload without passing the object.
Common situations: Dropping the argument while refactoring expressions; dynamic data variable that was removed from the call instead of being null; hand-writing JSON islands in templates and misplacing the argument.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- fromJson() requires a JSON string argument
- read() requires a path argument
- readBytes() requires a path argument
- context.get() requires a name argument
- invalid json: input is null or blank
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/598145126dbff71f.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/markup/MarkupContext.java:140
return switch (key) {
case "template" -> getTemplateName();
case "caller" -> getCallerTemplateName();
case "read" -> (JavaInvokable) args -> {
if (args.length == 0 || args[0] == null) {
throw new RuntimeException("read() requires a path argument");
}
return read(args[0].toString());
};
case "readBytes" -> (JavaInvokable) args -> {
if (args.length == 0 || args[0] == null) {
throw new RuntimeException("readBytes() requires a path argument");
}
return readBytes(args[0].toString());
};
case "toJson" -> (JavaInvokable) args -> {
// null IS a valid JSON-able value (`null`), so only the
// missing-arg case errors here.
if (args.length == 0) throw new RuntimeException("toJson() requires an object argument");
return toJson(args[0]);
};
case "fromJson" -> (JavaInvokable) args -> {
if (args.length == 0 || args[0] == null) {
throw new RuntimeException("fromJson() requires a JSON string argument");
}
return fromJson(args[0].toString());
};
// context.get(name, default?) for optional fragment params.
// Walks the current eval scope (`_` map first, then wrapped
// Thymeleaf scope). Returns the bound non-null value if found,
// else the default (or null when no default is given).
case "get" -> (JavaInvokable) args -> {
if (args.length == 0 || args[0] == null) {
throw new RuntimeException("context.get() requires a name argument");
}
String name = args[0].toString();
Object defaultValue = args.length > 1 ? args[1] : null;View on GitHub (pinned to a22eb90246)