iflytek/astron-agent · error · CustomException

END_NODE_SCHEMA_ERROR

END_NODE_SCHEMA_ERROR

Error message

Node {dep_msg_node} not found in node_run_status

What it means

END_NODE_SCHEMA_ERROR from end_node.async_execute: while waiting on the completion events of dependent message nodes, the end node found a dependency id in msg_or_end_node_deps[self.node_id].data_dep that has no entry in node_run_status. This means the workflow's dependency graph and the runtime status registry are inconsistent — a declared data dependency was never scheduled or its status event was never registered.

Solutions

  1. Open the End node's input/output variable configuration and remove or fix references to the missing node id (its name appears in the message).
  2. Ensure the referenced message node still exists in the canvas and is on an execution path that always runs, or make the dependency conditional.
  3. Re-save/publish the workflow so the dependency graph is rebuilt and node_run_status entries are registered for all deps.
  4. If importing old versions, validate the workflow schema for dangling node references before running.

Example fix

// before: End node references deleted node
{"deps": ["msg_node_1", "msg_node_deleted"]}
// after: remove the dangling reference
{"deps": ["msg_node_1"]}
Defensive patterns

Strategy: validation

Validate before calling

# before running, verify all end-node deps exist in the graph
dangling = set(end_node.data_dep) - set(graph.node_ids)
if dangling:
    raise ValueError(f"End node references missing nodes: {dangling}")

Type guard

def deps_exist(data_dep: list[str], node_run_status: dict) -> bool:
    return all(dep in node_run_status for dep in data_dep)

Try / catch

try:
    await end_node.async_execute(...)
except CustomException as e:
    if e.err_code == CodeEnum.END_NODE_SCHEMA_ERROR.code:
        logger.error("workflow schema issue: %s — re-save workflow and fix End node inputs", e.cause_error)

Prevention

When it happens

Trigger: An End node (or message-branch collection path) whose data_dep lists a message/output node id that never ran: the node was skipped by a branch condition, deleted/renamed in the workflow definition while the end node still references it, or the graph parser emitted a stale dependency.

Common situations: Editing a workflow to remove/rename a message node without updating the End node's inputs; conditional branches where the End node depends on a node inside a branch that didn't execute; imported/older workflow versions with dangling references.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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

Appendix: source

Thrown at core/workflow/engine/nodes/end/end_node.py:105

            # Process output in prompt mode if configured
            if self.outputMode == EndNodeOutputModeEnum.PROMPT_MODE.value:
                output_node_frame_data = await self.deal_output_stream_msg(
                    variable_pool=variable_pool,
                    template=self.template,
                    reasoning_template=self.reasoningTemplate,
                    callbacks=callbacks,
                    node_run_status=node_run_status,
                    span=span,
                )
                if output_node_frame_data:
                    content = output_node_frame_data.content
                    reasoning_content = output_node_frame_data.reasoning_content

            # Wait for all dependent message nodes to complete
            for dep_msg_node in msg_or_end_node_deps[self.node_id].data_dep:
                if dep_msg_node not in node_run_status:
                    raise CustomException(
                        err_code=CodeEnum.END_NODE_SCHEMA_ERROR,
                        cause_error=f"Node {dep_msg_node} not found in node_run_status",
                    )
                await node_run_status[dep_msg_node].complete.wait()

            # Collect output variables from the variable pool
            for end_input in self.input_identifier:
                outputs.update(
                    {
                        end_input: variable_pool.get_variable(
                            node_id=self.node_id, key_name=end_input, span=span
                        )
                    }
                )

            # Process templates for prompt mode output
            reasoning_template = ""
            if self.outputMode == EndNodeOutputModeEnum.PROMPT_MODE.value:

View on GitHub (pinned to 5e758547a8)