karatelabs/karate · error
Invalid number: bare '-'
Error message
Invalid number: bare '-'
What it means
Karate's internal JSON tokenizer (JsonParser.parseNumber) rejects a number token that begins with '-' but has no digits after it. JSON numbers may be negative, but a lone minus sign is not a valid number literal. The parser checks the character after '-' and throws a syntax error if the input ends or a non-numeric token follows.
Solutions
- Inspect the JSON string at the reported position and replace the bare '-' with a valid number (e.g. 0 or the intended negative value).
- If the JSON is built dynamically, ensure numeric variables are never interpolated as empty/null and quote placeholders that may be absent.
- Validate the payload with a JSON linter/parser before passing it to Karate to get a clearer diff of the malformed spot.
- If the value is genuinely optional, emit 'null' instead of '-' for missing numbers.
Example fix
// before
String json = "{\"amount\": " + amount + "}"; // amount == "" -> {"amount": -}
// after
String lit = (amount == null || amount.isEmpty()) ? "null" : amount;
String json = "{\"amount\": " + lit + "}"; Defensive patterns
Strategy: validation
Validate before calling
// Java: check the payload parses strictly before use
try (var p = new java.io.PushbackReader(new java.io.StringReader(json))) { /* or */ }
// simplest guard:
boolean valid = com.jayway.jsonpath.JsonPath.parse(json) != null; // or pre-scan for bare '-':
if (json.matches(".*[^0-9\\.eE]-\\s*[,}\\]].*") || json.trim().endsWith("-")) {
throw new IllegalArgumentException("bare '-' is not a valid JSON number");
} Try / catch
// Java
try {
Json json = Json.of(raw);
} catch (Exception e) {
if (e.getMessage() != null && e.getMessage().contains("Invalid number")) {
// sanitize placeholder tokens and retry
raw = raw.replaceAll("-\\s*([,}\\]]|$)", "null$1");
} else { throw e; }
} Prevention
- Never build JSON by string concatenation; use a serializer or Karate's Json object.
- Default missing numeric values to null or 0 in templates.
- Run generated payloads through a JSON linter in CI.
- Check for truncation when payloads cross size boundaries.
When it happens
Trigger: Calling the JSON parser (e.g. Json.of(...)/Json.parse on a string) with input where a value position contains '-' immediately followed by end-of-input or a delimiter, e.g. '[1, -]', '{"a": -}' or a trailing '-' after whitespace trimming.
Common situations: Hand-edited JSON config files where a negative value was never filled in; template/placeholder substitution that left '-' behind; string concatenation building JSON where a variable defaulted to empty; truncated responses ending mid-token.
Understand the failure class
Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.
Related errors
- Invalid number
- Invalid number: missing fraction digits
- Invalid number: missing exponent digits
- Unexpected token ' ' in JSON
- Expected string key in object
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/d17eb40c97f6d564.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/JsonParser.java:261
char h = s.charAt(pos + i);
int d;
if (h >= '0' && h <= '9') d = h - '0';
else if (h >= 'a' && h <= 'f') d = 10 + (h - 'a');
else if (h >= 'A' && h <= 'F') d = 10 + (h - 'A');
else throw syntaxError("Invalid hex digit '" + h + "' in \\u escape");
v = (v << 4) | d;
}
pos += 4;
return (char) v;
}
private Object parseNumber() {
int start = pos;
boolean isFloat = false;
if (s.charAt(pos) == '-') {
pos++;
if (pos >= len) {
throw syntaxError("Invalid number: bare '-'");
}
}
// integer part
char c = s.charAt(pos);
if (c == '0') {
pos++;
} else if (c >= '1' && c <= '9') {
pos++;
while (pos < len && (s.charAt(pos) >= '0' && s.charAt(pos) <= '9')) {
pos++;
}
} else {
throw syntaxError("Invalid number");
}
// fraction
if (pos < len && s.charAt(pos) == '.') {
isFloat = true;
pos++;View on GitHub (pinned to a22eb90246)