{"record":{"id":"a88d82fb247e9aaa","repo":"ScrapeGraphAI/Scrapegraph-ai","slug":"invalid-operator-placement-operators-cannot-be-ad","errorCode":null,"errorMessage":"Invalid operator placement: operators cannot be adjacent.","messagePattern":"Invalid operator placement: operators cannot be adjacent\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"scrapegraphai/nodes/base_node.py","lineNumber":188,"sourceCode":"        if (\n            expression[0] in \"&|\"\n            or expression[-1] in \"&|\"\n            or \"&&\" in expression\n            or \"||\" in expression\n            or \"&|\" in expression\n            or \"|&\" in expression\n        ):\n            raise ValueError(\"Invalid operator usage.\")\n\n        open_parentheses = close_parentheses = 0\n        for i, char in enumerate(expression):\n            if char == \"(\":\n                open_parentheses += 1\n            elif char == \")\":\n                close_parentheses += 1\n            # Check for invalid operator sequences\n            if char in \"&|\" and i + 1 < len(expression) and expression[i + 1] in \"&|\":\n                raise ValueError(\n                    \"Invalid operator placement: operators cannot be adjacent.\"\n                )\n\n        if open_parentheses != close_parentheses:\n            raise ValueError(\"Missing or unbalanced parentheses in expression.\")\n\n        def evaluate_simple_expression(exp: str) -> List[str]:\n            \"\"\"Evaluate an expression without parentheses.\"\"\"\n\n            for or_segment in exp.split(\"|\"):\n                and_segment = or_segment.split(\"&\")\n                if all(elem.strip() in state for elem in and_segment):\n                    return [\n                        elem.strip() for elem in and_segment if elem.strip() in state\n                    ]\n            return []\n\n        def evaluate_expression(expression: str) -> List[str]:","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/ScrapeGraphAI/Scrapegraph-ai/blob/532dfffbf6ee823a6c9cf8cfedc24a93bf026780/scrapegraphai/nodes/base_node.py#L170-L206","documentation":"Character-scan safeguard that fires when two operator characters ('&' or '|') are directly adjacent anywhere in the expression, e.g. '&|' or '|&' in the middle of the string. Even though error 41 catches some doubled-operator cases, this loop guards sequences at any position.","triggerScenarios":"input=\"a |& b\", input=\"a &| b\", or any expression where an '&' immediately follows a '|' (or vice versa) at an arbitrary position.","commonSituations":"Editing an existing expression and leaving a stray operator; string concatenation bugs when composing input expressions from lists, e.g. ' & '.join(parts) where a part is empty.","solutions":["Inspect the expression for adjacent operator characters and replace with a single operator","When building from lists, filter out empty tokens before joining with operators","Simplify the expression to well-formed '&'/'|' groups possibly with parentheses"],"exampleFix":"# before\nparts = ['a', '', 'b']\nexpr = ' & '.join(parts)  # -> 'a &  & b'\n# after\nexpr = ' & '.join(p for p in parts if p)","handlingStrategy":"validation","validationCode":"def no_adjacent_ops(expr: str) -> bool:\n    return all(not (c in '&|' and i+1 < len(expr) and expr[i+1] in '&|') for i, c in enumerate(expr))","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Filter empty tokens before joining expression parts with operators","Unit-test node input expressions as part of CI for custom nodes"],"tags":["scrapegraphai","node-config","expression-parsing","adjacent-operators"],"backgroundTag":"expression-syntax-invalid","analyzedSha":"532dfffbf6ee823a6c9cf8cfedc24a93bf026780","analyzedAt":"2026-08-28T15:19:38.821Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}