{"record":{"id":"f4e687f931946f15","repo":"ScrapeGraphAI/Scrapegraph-ai","slug":"invalid-operator-usage-f4e687","errorCode":null,"errorMessage":"Invalid operator usage.","messagePattern":"Invalid operator usage\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"scrapegraphai/utils/parse_state_keys.py","lineNumber":59,"sourceCode":"        + \"|\".join(re.escape(key) for key in state.keys())\n        + r\")(\\b\\s*\\b)(\"\n        + \"|\".join(re.escape(key) for key in state.keys())\n        + r\")\\b\"\n    )\n    if re.search(pattern, expression):\n        raise ValueError(\"Adjacent state keys found without an operator between them.\")\n\n    expression = expression.replace(\" \", \"\")\n\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(\"&\")","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/ScrapeGraphAI/Scrapegraph-ai/blob/532dfffbf6ee823a6c9cf8cfedc24a93bf026780/scrapegraphai/utils/parse_state_keys.py#L41-L77","documentation":"ValueError from parse_expression: operator misuse detected — the expression starts or ends with & or |, or contains doubled (&&, ||) or mixed (&|, |&) operators. Only single & and | with implicit precedence are supported.","triggerScenarios":"Expressions like '&key', 'key|', 'a && b', 'a || b', 'a &| b' passed to parse_expression.","commonSituations":"Copying Python/JS-style boolean syntax (&&, ||) into edge condition configs.","solutions":["Use single characters: 'a & b', 'a | b'","Remove leading/trailing operators","Parenthesize for grouping: '(a | b) & c'"],"exampleFix":"# before\nexpr = 'a && b || c'\n# after\nexpr = 'a & b | c'","handlingStrategy":"validation","validationCode":"import re\nassert not re.match(r\"^[&|]|[&|]$\", expr), \"leading/trailing operator\"\nassert not re.search(r\"&&|\\|\\||&\\||\\|&\", expr), \"double/mixed operators\"","typeGuard":"def is_valid_operator_syntax(expr) -> bool:\n    return not (expr[:1] in \"&|\" or expr[-1:] in \"&|\" or \"&&\" in expr or \"||\" in expr or \"&|\" in expr or \"|&\" in expr)","tryCatchPattern":"try:\n    keys = parse_expression(expr, state)\nexcept ValueError as e:\n    fixed = expr.replace(\"&&\", \"&\").replace(\"||\", \"|\")\n    keys = parse_expression(fixed, state)","preventionTips":["Use single & and | only","Translate && / || from other languages before config entry","Lint expressions in tests"],"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"}