{"record":{"id":"03296383245ff3ee","repo":"dgtlmoon/changedetection.io","slug":"xpath-not-permitted-in-this-field","errorCode":null,"errorMessage":"XPath not permitted in this field!","messagePattern":"XPath not permitted in this field!","errorType":"validation","errorClass":"ValidationError","httpStatus":null,"severity":"warning","filePath":"changedetectionio/forms.py","lineNumber":696,"sourceCode":"        self.allow_xpath = allow_xpath\n        self.allow_json = allow_json\n\n    def __call__(self, form, field):\n\n        if isinstance(field.data, str):\n            data = [field.data]\n        else:\n            data = field.data\n\n        for line in data:\n        # Nothing to see here\n            if not len(line.strip()):\n                return\n\n            # Does it look like XPath?\n            if line.strip()[0] == '/' or line.strip().startswith('xpath:'):\n                if not self.allow_xpath:\n                    raise ValidationError(\"XPath not permitted in this field!\")\n                from lxml import etree, html\n                import elementpath\n                from changedetectionio.html_tools import SafeXPath3Parser, lxml_guard, lxml_html_parser\n                line = line.replace('xpath:', '')\n\n                try:\n                    # Runs on a Flask request thread - must share the worker's lxml lock.\n                    with lxml_guard():\n                        tree = html.fromstring(\"<html></html>\", parser=lxml_html_parser())\n                        elementpath.select(tree, line.strip(), parser=SafeXPath3Parser)\n                except elementpath.ElementPathError as e:\n                    message = field.gettext('\\'%(expression)s\\' is not a valid XPath expression. (%(error)s)')\n                    raise ValidationError(message % {'expression': line, 'error': str(e)})\n                except:\n                    raise ValidationError(\"A system-error occurred when validating your XPath expression\")\n\n            if line.strip().startswith('xpath1:'):\n                if not self.allow_xpath:","sourceCodeStart":678,"sourceCodeEnd":714,"githubUrl":"https://github.com/dgtlmoon/changedetection.io/blob/5d9c7c6da76340597243e8163c4f2439237fa0e8/changedetectionio/forms.py#L678-L714","documentation":"In ValidateCSSJSONXPATHInput.__call__, each non-empty line of the field is inspected: if it starts with '/' or 'xpath:' it is treated as an XPath expression. When the validator instance was constructed with allow_xpath=False, any XPath-looking input is rejected immediately with \"XPath not permitted in this field!\" before any parsing occurs.","triggerScenarios":"Submitting a filter/processing rule value beginning with '/' or 'xpath:' (e.g. '//div[@id=\"x\"]' or 'xpath://h1') to a field whose validator was created with allow_xpath=False (fields that only accept CSS/JSON paths).","commonSituations":"Pasting an XPath selector into a CSS-selector-only field, or using xpath: prefix in a form that was configured without XPath support (operator restriction or field type).","solutions":["Move the XPath expression to a field that supports XPath (allow_xpath=True)","Convert the expression to a CSS selector, e.g. '//div[@id=\"main\"]' -> 'div#main'","Remove the leading 'xpath:' prefix or leading '/' if it was accidental"],"exampleFix":"# before (in a CSS-only field)\n//div[@id=\"main\"]\n# after\ndiv#main\n","handlingStrategy":"type-guard","validationCode":"def line_permitted(line: str, allow_xpath: bool) -> bool:\n    s = line.strip()\n    looks_like_xpath = s.startswith('/') or s.startswith('xpath:')\n    return allow_xpath or not looks_like_xpath\n","typeGuard":"def is_xpath_line(line: str) -> bool:\n    s = line.strip()\n    return s.startswith('/') or s.startswith('xpath:')\n","tryCatchPattern":"from wtforms import ValidationError\ntry:\n    form.validate()\nexcept ValidationError as e:\n    if 'XPath not permitted' in str(e):\n        hint('Move the XPath expression to an XPath-capable field')\n","preventionTips":["Know which fields accept XPath before pasting selectors","Prefer CSS selectors where possible","Keep a field-type cheat sheet in the UI"],"tags":["xpath","css-selector","wtforms","changedetectionio","input-validation"],"backgroundTag":"selector-syntax-not-allowed","analyzedSha":"5d9c7c6da76340597243e8163c4f2439237fa0e8","analyzedAt":"2026-08-27T19:41:16.067Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}