ScrapeGraphAI/Scrapegraph-ai · error · ValueError

node_type must be 'node' or 'conditional_node', got '{node_t

Error message

node_type must be 'node' or 'conditional_node', got '{node_type}'

What it means

BaseNode.__init__ validates its node_type argument against the two allowed values ('node' and 'conditional_node'); anything else — including None, 'Node', or a custom string — raises immediately when the node object is constructed. node_type determines how BaseGraph routes execution, so it cannot be free-form.

Source

Thrown at scrapegraphai/nodes/base_node.py:65

    def __init__(
        self,
        node_name: str,
        node_type: str,
        input: str,
        output: List[str],
        min_input_len: int = 1,
        node_config: Optional[dict] = None,
    ):
        self.node_name = node_name
        self.input = input
        self.output = output
        self.min_input_len = min_input_len
        self.node_config = node_config
        self.logger = get_logger()

        if node_type not in ["node", "conditional_node"]:
            raise ValueError(
                f"node_type must be 'node' or 'conditional_node', got '{node_type}'"
            )
        self.node_type = node_type

    @abstractmethod
    def execute(self, state: dict) -> dict:
        """
        Execute the node's logic based on the current state and update it accordingly.

        Args:
            state (dict): The current state of the graph.

        Returns:
            dict: The updated state after executing the node's logic.
        """

        pass

View on GitHub (pinned to 532dfffbf6)

Solutions

  1. Use node_type='node' for standard nodes and 'conditional_node' for nodes that return the next node's name.
  2. Usually the right fix is to inherit from Node or ConditionalNode in scrapegraphai.nodes, which set node_type for you.
  3. Check for typos/case if passing a computed value.

Example fix

# before
class MyNode(BaseNode):
    def __init__(self, **kwargs):
        super().__init__(node_type='conditional', **kwargs)

# after
from scrapegraphai.nodes import ConditionalNode
class MyNode(ConditionalNode):
    pass
Defensive patterns

Strategy: validation

Validate before calling

assert node_type in ('node', 'conditional_node'), f"invalid node_type {node_type!r}"

Type guard

def is_valid_node_type(t: str) -> bool:
    return t in ('node', 'conditional_node')

Try / catch

try:
    n = MyNode(node_type=nt, ...)
except ValueError as e:
    if 'node_type must be' in str(e):
        nt = 'conditional_node' if is_router else 'node'
        n = MyNode(node_type=nt, ...)
    else:
        raise

Prevention

When it happens

Trigger: Subclassing BaseNode (or ConditionalNode) and passing node_type='custom' / 'router' / 'conditionalNode'; passing node_type=None in a custom constructor; calling BaseNode(...) directly for testing.

Common situations: Writing custom nodes for the first time and guessing the type string; case mismatches ('Conditional_Node'); refactoring where a variable holding the type is unset.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of ScrapeGraphAI/Scrapegraph-ai@532dfffbf6 (2026-08-28). Data as JSON: /api/errors/4147cdf9a4718192. Report an issue: GitHub.