{"record":{"id":"d3b6499c79bf3590","repo":"ScrapeGraphAI/Scrapegraph-ai","slug":"adjacent-state-keys-found-without-an-operator-betw-d3b649","errorCode":null,"errorMessage":"Adjacent state keys found without an operator between them.","messagePattern":"Adjacent state keys found without an operator between them\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"scrapegraphai/utils/parse_state_keys.py","lineNumber":47,"sourceCode":"\n    This function evaluates the expression to determine the\n    logical inclusion of state keys based on provided boolean logic.\n    It checks for syntax errors such as unbalanced parentheses,\n    incorrect adjacency of operators, and empty expressions.\n    \"\"\"\n\n    if not expression:\n        raise ValueError(\"Empty expression.\")\n\n    pattern = (\n        r\"\\b(\"\n        + \"|\".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 == \")\":","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/ScrapeGraphAI/Scrapegraph-ai/blob/532dfffbf6ee823a6c9cf8cfedc24a93bf026780/scrapegraphai/utils/parse_state_keys.py#L29-L65","documentation":"ValueError from parse_expression: two state keys appear next to each other with whitespace but no operator between them (regex matches 'key1 key2'). Keys must be joined explicitly with & or |.","triggerScenarios":"Calling parse_expression('fetch_node parse_node', state) — implicit 'and' via a space is not supported.","commonSituations":"Writing expressions in a Python-like style ('a b' meaning and) or a typo deleting the & between keys.","solutions":["Insert explicit operators: 'fetch_node & parse_node'","Validate the expression string before passing it (e.g. unit-test edge conditions)"],"exampleFix":"# before\nexpr = 'fetch_node parse_node'\n# after\nexpr = 'fetch_node & parse_node'","handlingStrategy":"validation","validationCode":"import re\nkeys = list(state)\nif re.search(r\"\\b(\" + \"|\".join(map(re.escape, keys)) + r\")\\s+(\" + \"|\".join(map(re.escape, keys)) + r\")\\b\", expression):\n    raise ValueError(\"adjacent keys\")  # or auto-insert '&'","typeGuard":null,"tryCatchPattern":"try:\n    keys = parse_expression(expr, state)\nexcept ValueError as e:\n    expr2 = re.sub(r\"(?<=[a-z_])\\s+(?=[a-z_])\", \" & \", expr2)\n    keys = parse_expression(expr2, state)","preventionTips":["Always write explicit & / | between keys","Generate expressions from key lists joined by '&'","Reject implicit-and style in code review"],"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"}