{"record":{"id":"110e51baa38b238a","repo":"ScrapeGraphAI/Scrapegraph-ai","slug":"invalid-operator-placement-operators-cannot-be-ad-110e51","errorCode":null,"errorMessage":"Invalid operator placement: operators cannot be adjacent.","messagePattern":"Invalid operator placement: operators cannot be adjacent\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"scrapegraphai/utils/parse_state_keys.py","lineNumber":68,"sourceCode":"\n    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        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):\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 [elem.strip() for elem in and_segment if elem.strip() in state]\n        return []\n\n    def evaluate_expression(expression):\n        while \"(\" in expression:\n            start = expression.rfind(\"(\")\n            end = expression.find(\")\", start)\n            sub_exp = expression[start + 1 : end]","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/ScrapeGraphAI/Scrapegraph-ai/blob/532dfffbf6ee823a6c9cf8cfedc24a93bf026780/scrapegraphai/utils/parse_state_keys.py#L50-L86","documentation":"ValueError from parse_expression: two operator characters are adjacent (e.g. '&|' or '|&' after spaces are stripped). This is a per-character scan complementing the doubled-operator checks.","triggerScenarios":"Expressions like 'a & | b' — after space removal it becomes 'a&|b', triggering this error during the character loop.","commonSituations":"Typos or malformed concatenation of condition fragments producing adjacent operators.","solutions":["Fix the expression to have exactly one operator between operands","Build expressions programmatically from validated tokens instead of string concatenation"],"exampleFix":"# before\nexpr = 'a & | b'\n# after\nexpr = 'a | b'","handlingStrategy":"validation","validationCode":"compacted = expression.replace(\" \", \"\")\nassert not re.search(r\"[&|]{2,}\", compacted), \"adjacent operators\"","typeGuard":null,"tryCatchPattern":"try:\n    keys = parse_expression(expr, state)\nexcept ValueError:\n    expr = re.sub(r\"\\s*([&|])\\s*([&|])\\s*\", r\"\\1\", expr)  # collapse accidental doubles\n    keys = parse_expression(expr, state)","preventionTips":["Avoid hand-concatenating condition fragments with operators","Strip stray spaces around operators before parsing","Build expressions from structured tokens"],"tags":["expression","state-keys","validation"],"backgroundTag":"expression-syntax-error","analyzedSha":"532dfffbf6ee823a6c9cf8cfedc24a93bf026780","analyzedAt":"2026-08-28T15:19:38.821Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}