{"record":{"id":"8c5118392cddba50","repo":"karatelabs/karate","slug":"unexpected-end-of-json-input","errorCode":null,"errorMessage":"Unexpected end of JSON input","messagePattern":"Unexpected end of JSON input","errorType":"exception","errorClass":"SyntaxError","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/JsonParser.java","lineNumber":55,"sourceCode":" *\n * <p>Numeric narrowing: integer values in {@code int} range → {@link Integer};\n * integer values fitting in {@code long} → {@link Long}; larger integers →\n * {@link BigInteger}; any literal with a fractional part or exponent →\n * {@link Double}. See {@code JsonParserTest} for the pinned contract.\n *\n * <p>Designed to be allocated per call ({@link ParseState} is a private,\n * non-static inner class); the {@code parse} entry point is thread-safe by\n * construction — no shared mutable state.\n */\npublic final class JsonParser {\n\n    private JsonParser() {\n        // static utility\n    }\n\n    public static Object parse(String input) {\n        if (input == null) {\n            throw JsErrorException.syntaxError(\"Unexpected end of JSON input\");\n        }\n        ParseState state = new ParseState(input);\n        state.skipWs();\n        Object value = state.parseValue();\n        state.skipWs();\n        if (state.pos != input.length()) {\n            throw state.syntaxError(\"Unexpected token after JSON value\");\n        }\n        return value;\n    }\n\n    private static final class ParseState {\n\n        private final String s;\n        private final int len;\n        private int pos;\n\n        ParseState(String s) {","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/JsonParser.java#L37-L73","documentation":"JsonParser.parse throws this SyntaxError when the input string is null, matching how browsers report empty JSON bodies ('Unexpected end of JSON input'). Because a null input contains zero characters, the parser treats it as truncated JSON rather than a distinct null case.","triggerScenarios":"JsonParser.parse(null) directly; in Karate JS, JSON.parse(variable) where the variable is null/empty — e.g. reading a response body or file that came back empty.","commonSituations":"HTTP responses with 204 No Content or empty bodies being fed to JSON.parse; empty config or data files read as empty strings/null; variable initialized to null but expected to hold a JSON string; upstream service returning no payload.","solutions":["Check for null/empty before parsing: if (str && str.length) return JSON.parse(str).","Assign a default: const data = body ? JSON.parse(body) : {}.","Fix the upstream source so it actually returns a JSON string (check API call, file read, env var).","Catch the syntax error and treat empty input as a sentinel value where appropriate."],"exampleFix":"// before\nconst cfg = JSON.parse(body); // body is null\n\n// after\nconst cfg = body ? JSON.parse(body) : {};","handlingStrategy":"validation","validationCode":"if (input == null || input.length === 0) throw new Error('cannot parse empty JSON input');\nvar value = JSON.parse(input);","typeGuard":"function isNonEmptyString(s) { return typeof s === 'string' && s.length > 0; }","tryCatchPattern":"try { return JSON.parse(input); } catch (e) { if (String(e).indexOf('Unexpected end of JSON input') !== -1) return null; throw e; }","preventionTips":["Always check body/file/env-var content is non-empty before JSON.parse","Give 204/empty responses an explicit default value","Initialize JSON-holding variables with a string, not null","Log raw input when parse fails to spot empty sources early"],"tags":["javascript","json","syntaxerror","null"],"backgroundTag":"json-parse-error","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"}