iflytek/astron-agent · error · CustomException

NODE_RUN_ERROR

NODE_RUN_ERROR

Error message

{run_result.error}

What it means

When a node execution finishes with a non-SUCCEEDED status, _execute_with_error_handling raises NODE_RUN_ERROR whose message is the node's own run_result.error, feeding it into the engine's retry logic. This is the generic 'node failed' wrapper — the real cause is inside the message.

Solutions

  1. Read err_msg — it contains the node's own error describing the root cause
  2. Enable the node's retry config or fail branch to tolerate transient failures
  3. Fix the underlying node input (missing variables, invalid model credentials)
  4. Check node/plugin logs for the failing execute call
Defensive patterns

Strategy: try-catch

Try / catch

try:
    result, retry = await engine._execute_with_error_handling(node)
except CustomException as e:
    if e.err_code == CodeEnum.NODE_RUN_ERROR:
        logger.warning("node %s failed: %s", node.node_id, e.err_msg)  # err_msg holds root cause
        route_to_fail_branch(node.node_id, e)

Prevention

When it happens

Trigger: Any node strategy returns a run_result with status FAILED/other non-success (API call failed inside the node, tool error, LLM refusal, missing input variable); the exception path is used so retry/fail-branch logic kicks in.

Common situations: LLM node hitting rate limits or invalid API keys; tool/plugin node returning errors; upstream variable missing so the node marks itself failed; timeouts reported as failures by the node itself.

Related errors


AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12). Data as JSON: /api/errors/5d7aee60003ed1aa. Report an issue: GitHub.

Appendix: source

Thrown at core/workflow/engine/dsl_engine.py:1256

        max_retries = retry_config.max_retries
        node_type = node.node_id.split("::")[0]

        for attempt in range(max_retries + 1):
            try:
                # Select execution method based on node type
                if node_type in CONTINUE_ON_ERROR_NOT_STREAM_NODE_TYPE:
                    run_result = await self._execute_non_stream_node(
                        node, span_context, retry_config
                    )
                else:
                    run_result = await self._execute_stream_node(node, span_context)

                # Check execution result
                if run_result.status == WorkflowNodeExecutionStatus.SUCCEEDED:
                    return run_result, False

                # If not successful status, raise exception to enter retry logic
                raise CustomException(
                    CodeEnum.NODE_RUN_ERROR,
                    err_msg=f"{run_result.error}",
                    cause_error=f"{run_result.error}",
                )

            except Exception as error:
                # Use chain of responsibility to handle errors
                result, should_retry = await self.error_handler_chain.handle_error(
                    error, node, self.engine_ctx, attempt, span_context
                )

                if result is not None:
                    # Error handler returned a result
                    fail_branch = (
                        retry_config.error_strategy == ErrorHandler.FailBranch.value
                    )
                    return result, fail_branch

View on GitHub (pinned to 5e758547a8)