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
- 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).
- Ensure the referenced message node still exists in the canvas and is on an execution path that always runs, or make the dependency conditional.
- Re-save/publish the workflow so the dependency graph is rebuilt and node_run_status entries are registered for all deps.
- 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
- Remove/rename message nodes via the canvas so dependent End-node references update automatically
- Validate workflow graphs for dangling references before publish
- Make End-node inputs conditional when they depend on branch-internal nodes
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
- VARIABLE_POOL_SET_PARAMETER_ERROR
- VARIABLE_POOL_GET_PARAMETER_ERROR
- PROTOCOL_BUILD_ERROR
- UPDATE_BOT_FAILED
- BOT_CHAIN_SUBMIT_ERROR
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)