{"record":{"id":"659efb38b25a0f98","repo":"karatelabs/karate","slug":"expected-number-instead-of","errorCode":null,"errorMessage":"expected number instead of: ","messagePattern":"expected number instead of: ","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"karate-core/src/main/java/io/karatelabs/match/Operation.java","lineNumber":811,"sourceCode":"                mo.execute();\n                return mo.pass;\n            default:\n                throw new RuntimeException(\"unexpected type (match within): \" + actual.type);\n        }\n    }\n\n    private static BigDecimal toBigDecimal(Object o) {\n        if (o instanceof BigDecimal bd) {\n            return bd;\n        } else if (o instanceof BigInteger bi) {\n            return new BigDecimal(bi);\n        } else if (o instanceof Long || o instanceof Integer || o instanceof Short || o instanceof Byte) {\n            // integral types convert exactly, going via doubleValue() would lose bits beyond 2^53\n            return BigDecimal.valueOf(((Number) o).longValue());\n        } else if (o instanceof Number n) {\n            return BigDecimal.valueOf(n.doubleValue());\n        } else {\n            throw new RuntimeException(\"expected number instead of: \" + o);\n        }\n    }\n\n    boolean pass() {\n        pass = true;\n        return true;\n    }\n\n    boolean fail(String reason) {\n        pass = false;\n        if (reason == null) {\n            return false;\n        }\n        failReason = failReason == null ? reason : reason + \" | \" + failReason;\n        context.root.failures.add(this);\n        return false;\n    }\n","sourceCodeStart":793,"sourceCodeEnd":829,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/match/Operation.java#L793-L829","documentation":"The match Operation engine coerces match operands to BigDecimal for numeric comparisons. When the operand is neither a String parseable as a number nor any Number type (Long/Integer/Short/Byte/other Number), it throws 'expected number instead of: <value>'. The library throws because a numeric operation received a non-numeric value.","triggerScenarios":"Invoking numeric match operations (e.g. greaterThan/lessThan-style comparisons, arithmetic within match macros) with an actual or expected value that is a Map, List, boolean, or null instead of a number or numeric string.","commonSituations":"Comparing a JSON field that is sometimes null, comparing against an array element that turned out to be an object, or passing a boolean/string like 'true' where a number was expected in match expressions.","solutions":["Inspect the value printed in the message and fix the actual data source so it yields a number","Coerce the operand explicitly before matching (e.g. Integer.parseInt/Double.parseDouble for strings)","Add a preceding type/shape assertion (Match.that(x).isTypeOf(\"number\")) to fail earlier with a clearer message","If the value can be null, guard the comparison with a null check before invoking the numeric match"],"exampleFix":"// before\nMatch.that(response.count).isGreaterThan(\"ten\"); // non-numeric operand\n// after\nMatch.that(Integer.parseInt(response.count)).isGreaterThan(10);","handlingStrategy":"validation","validationCode":"if (!(operand instanceof Number) && !(operand instanceof String s && s.matches(\"-?\\\\d+(\\\\.\\\\d+)?\"))) {\n    throw new IllegalArgumentException(\"numeric match needs a number, got: \" + operand);\n}","typeGuard":"static boolean isNumeric(Object o) {\n    return o instanceof Number || (o instanceof String s && s.matches(\"-?\\\\d+(\\\\.\\\\d+)?\"));\n}","tryCatchPattern":"try {\n    Match.that(actual).isGreaterThan(0);\n} catch (RuntimeException e) {\n    if (e.getMessage().startsWith(\"expected number instead of\")) {\n        // coerce or skip numeric assertion\n    }\n}","preventionTips":["Coerce JSON string fields to numbers before numeric matches","Null-check optional fields before comparisons","Add isTypeOf(\"number\") assertions upstream"],"tags":["match","numeric","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}