{"record":{"id":"7e8314f274c60f07","repo":"karatelabs/karate","slug":"cannot-set-xpath-on-non-xml-variable","errorCode":null,"errorMessage":"cannot set xpath on non-XML variable: ","messagePattern":"cannot set xpath on non-XML variable: ","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"karate-core/src/main/java/io/karatelabs/core/KarateJs.java","lineNumber":616,"sourceCode":"\n                // Check if this is XPath (path starts with /) or target is XML\n                if (path.startsWith(\"/\") || target instanceof Node) {\n                    // XPath set on XML\n                    Document doc;\n                    if (target instanceof Document) {\n                        doc = (Document) target;\n                    } else if (target instanceof Node) {\n                        doc = ((Node) target).getOwnerDocument();\n                    } else if (target == null) {\n                        // Create new XML document\n                        doc = Xml.newDocument();\n                        engine.put(name, doc);\n                    } else if (target instanceof String && StringUtils.isXml((String) target)) {\n                        // Convert XML string to Document\n                        doc = Xml.toXmlDoc((String) target);\n                        engine.put(name, doc);\n                    } else {\n                        throw new RuntimeException(\"cannot set xpath on non-XML variable: \" + name);\n                    }\n                    if (value instanceof Node) {\n                        Xml.setByPath(doc, path, (Node) value);\n                    } else {\n                        Xml.setByPath(doc, path, value == null ? \"\" : value.toString());\n                    }\n                } else {\n                    // Route through Json (Jayway) for full JSONPath semantics:\n                    // dotted paths, [N] indices, $.foo[] array append, and\n                    // ['hy-phen'] bracket-quoted keys. Mirrors\n                    // the `set var.path = value` Gherkin step.\n                    if (target == null) {\n                        target = new java.util.LinkedHashMap<>();\n                        engine.put(name, target);\n                    }\n                    Json.of(target).set(path, value);\n                }\n            }","sourceCodeStart":598,"sourceCodeEnd":634,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/core/KarateJs.java#L598-L634","documentation":"When karate.set() is given an XPath-style path (a third path argument), the target variable must be XML — a Node/Document or an XML string that can be converted to a Document. Karate throws this with the variable name appended when the target is any other type (JSON object, string that is not XML, number, etc.), since XPath cannot operate on it.","triggerScenarios":"karate.set('myVar', '/root/child', value) where myVar holds JSON or a non-XML string; using XPath syntax on a JSON variable by mistake.","commonSituations":"Mixing up JSON-path and XPath set syntax; a variable that was expected to hold XML but was reassigned to JSON earlier in the scenario; response parsed as JSON instead of XML.","solutions":["Use JSON-path style with JSON: karate.set('myVar', '$.child', value).","Ensure the target variable contains XML (Document or XML string) before the XPath set.","Convert data first, e.g. assign an XML response to the variable, then do the XPath set.","Verify the variable name — the message names the offending variable."],"exampleFix":"// before\nkarate.set('jsonVar', '/root/name', 'Bob');\n// after\nkarate.set('jsonVar', '$.name', 'Bob');","handlingStrategy":"validation","validationCode":"// before an XPath set, confirm the target is XML\nif (typeof karate.get('xmlVar') === 'string' && karate.get('xmlVar').trim().charAt(0) !== '<') throw new Error('xmlVar is not XML');","typeGuard":"function isXmlLike(v) { return v != null && (typeof Node !== 'undefined' && v instanceof Node || (typeof v === 'string' && v.trim().charAt(0) === '<')); }","tryCatchPattern":"try { karate.set(name, '/root/child', value); }\ncatch (e) { if ((e.message || '').indexOf('cannot set xpath on non-XML variable') >= 0) karate.set(name, '$.child', value); else throw e; }","preventionTips":["Match path syntax to data type: JSON-path ($.) for JSON, XPath (/) for XML.","Assert the variable holds XML (response is xml) before XPath sets.","Avoid reassigning XML variables to JSON mid-scenario.","The error names the offending variable — check its last assignment."],"tags":["xml","xpath","type-mismatch"],"backgroundTag":"incompatible-source-type","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"}