iflytek/astron-agent · error · ValueError
node is not exist
Error message
{source_node_id} node is not exist What it means
Chains._record_iteration_start looks up the iteration node for an incoming edge in the node dict and raises ValueError when the source node id (an ITERATION node, by prefix) is missing. This happens while Chains processes edges via _deal_edges to record which node starts an iteration. Unlike CustomException paths this is a plain ValueError, so it surfaces as an unexpected internal failure rather than a structured workflow error.
Solutions
- Ensure the iteration node with that id exists in the DSL nodes map before/alongside the edge
- Remove stale edges attached to deleted iteration nodes
- Re-save the workflow in the editor to regenerate consistent edges
- Catch ValueError in tooling that programmatically edits DSLs and repair dangling edges
Example fix
# before: edge exists, node removed
{"edges": [{"source": "iteration::abc"}], "nodes": []}
# after: keep node and edge consistent
{"edges": [{"source": "iteration::abc"}], "nodes": [{"id": "iteration::abc"}]} Defensive patterns
Strategy: validation
Validate before calling
def check_iteration_edges(dsl):
ids = {n["id"] for n in dsl["nodes"]}
for e in dsl["edges"]:
if e["source"].startswith("iteration::") and e["source"] not in ids:
raise ValueError(f"missing iteration node {e['source']}") Type guard
def iteration_node_exists(node_dict, source_id):
return source_id.startswith("iteration::") and source_id in node_dict Try / catch
try:
chains = Chains.build(dsl)
except ValueError as e:
if "node is not exist" in str(e):
# remove/repair the dangling iteration edge before rebuilding
...
raise Prevention
- Delete edges together with their iteration nodes when editing DSLs programmatically
- Re-export workflows from the editor after structural edits
- Diff node ids across workflow versions before merging
When it happens
Trigger: An edge whose source id has the 'iteration' prefix (e.g. 'iteration::<id>') but the corresponding node is not present in node_dict — dangling edge into/out of an iteration node after the node was deleted or the DSL was hand-edited.
Common situations: Deleting an iteration node in the editor while its edges persist; merging workflow versions where the iteration node id changed; importing partial DSLs that contain edges but not the iteration node definition.
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
- UPDATE_BOT_FAILED
- BOT_CHAIN_SUBMIT_ERROR
- DATA_NOT_FOUND
- WORKFLOW_VERSION_PUBLISH_FAILED
- BOT_CHAIN_SUBMIT_ERROR
AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12).
Data as JSON: /api/errors/85f6a47e5884c6e9.
Report an issue: GitHub.
Appendix: source
Thrown at core/workflow/engine/entities/chains.py:215
return target_node_id
return current_end_node_id
def _record_iteration_start(
self,
iteration_dict: Dict[str, str],
node_dict: Dict[str, Node],
source_node_id: str,
) -> None:
"""
Record the start node configured for an iteration node.
"""
source_node_id_prefix = source_node_id.split("::")[0]
if source_node_id_prefix != NodeType.ITERATION.value:
return
iter_node: Node | None = node_dict.get(source_node_id)
if iter_node is None:
raise ValueError(f"{source_node_id} node is not exist")
start_id = iter_node.data.nodeParam.get("IterationStartNodeId")
iteration_dict[source_node_id] = str(start_id or "")
def _record_loop_start(
self,
loop_dict: Dict[str, str],
node_dict: Dict[str, Node],
source_node_id: str,
) -> None:
"""
Record the start node configured for a loop node.
"""
source_node_id_prefix = source_node_id.split("::")[0]
if source_node_id_prefix != NodeType.LOOP.value:
return
loop_node: Node | None = node_dict.get(source_node_id)View on GitHub (pinned to 5e758547a8)