{"record":{"id":"5348ba3e20ce5687","repo":"karatelabs/karate","slug":"expected-string-key-in-object","errorCode":null,"errorMessage":"Expected string key in object","messagePattern":"Expected string key in object","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/JsonParser.java","lineNumber":115,"sourceCode":"                        return parseNumber();\n                    }\n                    throw syntaxError(\"Unexpected token '\" + c + \"' in JSON\");\n            }\n        }\n\n        private Map<String, Object> parseObject() {\n            // we know s.charAt(pos) == '{'\n            pos++;\n            Map<String, Object> map = new LinkedHashMap<>();\n            skipWs();\n            if (pos < len && s.charAt(pos) == '}') {\n                pos++;\n                return map;\n            }\n            while (true) {\n                skipWs();\n                if (pos >= len || s.charAt(pos) != '\"') {\n                    throw syntaxError(\"Expected string key in object\");\n                }\n                String key = parseString();\n                skipWs();\n                if (pos >= len || s.charAt(pos) != ':') {\n                    throw syntaxError(\"Expected ':' after object key\");\n                }\n                pos++;\n                skipWs();\n                Object value = parseValue();\n                // RFC 8259: behavior of duplicate keys is unspecified; we keep\n                // the last value (matches json-smart parseKeepingOrder).\n                map.put(key, value);\n                skipWs();\n                if (pos >= len) {\n                    throw syntaxError(\"Unexpected end of JSON input in object\");\n                }\n                char c = s.charAt(pos);\n                if (c == ',') {","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/JsonParser.java#L97-L133","documentation":"Within parseObject, every key must be a double-quoted string per RFC 8259. If after skipping whitespace the next character is not `\"` (or input is exhausted), the parser throws \"Expected string key in object\". This rejects JS-style unquoted or single-quoted keys.","triggerScenarios":"Parsing an object like `{name: 1}` (unquoted key), `{'name': 1}` (single-quoted key), or a truncated object `{\"a\":1,` where the parser expects the next key and hits `}` end-of-input.","commonSituations":"Hand-written JSON copied from JavaScript object literals; template-generated JSON with missing quotes; config files edited by hand and saved with JS-literal syntax.","solutions":["Quote every object key with double quotes: `{\"name\": 1}`.","Convert single quotes around keys to double quotes.","Fix truncation so the object closes properly with `}` instead of ending where a key is expected."],"exampleFix":"// before\nvar x = JSON.parse('{name: \"a\"}');\n\n// after\nvar x = JSON.parse('{\"name\": \"a\"}');","handlingStrategy":"validation","validationCode":"// detect JS-style keys before parsing\nif (/'[\\w-]+'\\s*:|(^|\\{)\\s*[A-Za-z_$][\\w$]*\\s*:/.test(input)) {\n    throw new IllegalArgumentException('object keys must be double-quoted JSON strings');\n}","typeGuard":null,"tryCatchPattern":"try {\n    var obj = JSON.parse(input);\n} catch (e) {\n    if (('' + e).indexOf('Expected string key') >= 0) {\n        console.log('check that every object key is \"quoted\"');\n    }\n    throw e;\n}","preventionTips":["Always double-quote object keys in JSON.","Do not paste JavaScript object literals where JSON is expected.","Validate JSON files with a linter before committing."],"tags":["json","parser","syntax-error"],"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-16T19:17:19.609Z"}