argoproj/argo-workflows · error
key was not found for %s
Error message
key was not found for %s
What it means
Nodes is a map of node ID to NodeStatus on WorkflowStatus. The Get helper returns a pointer to the node status, and when the requested key (node ID) is not present in the map it returns this error naming the missing key, rather than a nil pointer.
Source
Thrown at pkg/apis/workflow/v1alpha1/workflow_types.go:2030
func (n Nodes) Any(f func(NodeStatus) bool) bool {
return n.Find(f) != nil
}
func (n Nodes) Find(f func(NodeStatus) bool) *NodeStatus {
for _, i := range n {
if f(i) {
return &i
}
}
return nil
}
// Get a NodeStatus from the hashmap of Nodes.
// Return a nil along with an error if non existent.
func (n Nodes) Get(key string) (*NodeStatus, error) {
val, ok := n[key]
if !ok {
return nil, fmt.Errorf("key was not found for %s", key)
}
return &val, nil
}
// Has checks if the Nodes map has a key entry.
func (n Nodes) Has(key string) bool {
_, err := n.Get(key)
return err == nil
}
// GetPhase returns the Phase of a Node by key.
func (n Nodes) GetPhase(key string) (*NodePhase, error) {
val, err := n.Get(key)
if err != nil {
return nil, err
}
return &val.Phase, nil
}View on GitHub (pinned to 35bff19146)
Solutions
- Verify the nodeID exists with Nodes.Has(nodeID) before calling Get
- Re-fetch/hydrate the Workflow object — node status may be offloaded or from a stale copy
- Use the correct node ID obtained from the workflow's Nodes map (list keys) instead of constructing one
Example fix
// before
node, err := wf.Status.Nodes.Get(nodeID) // error if absent
// after
if !wf.Status.Nodes.Has(nodeID) {
return fmt.Errorf("node %s not present", nodeID)
}
node, err := wf.Status.Nodes.Get(nodeID) Defensive patterns
Strategy: type-guard
Validate before calling
if nodeID == "" || !wf.Status.Nodes.Has(nodeID) {
return errors.New("node does not exist in workflow status")
} Type guard
func nodeExists(n Nodes, id string) bool {
return n.Has(id)
} Try / catch
node, err := wf.Status.Nodes.Get(nodeID)
if err != nil {
return fmt.Errorf("node %s not found (workflow may have been retried or status offloaded): %w", nodeID, err)
} Prevention
- Always check Nodes.Has() before Get
- Re-fetch the Workflow instead of caching Nodes across reconciles
- Never construct node IDs manually; read them from Status.Nodes
When it happens
Trigger: Calling wf.Status.Nodes.Get(nodeID) with a node ID that does not exist — e.g. a stale/incorrect nodeID, querying before the workflow has started, or after node status was truncated/offloaded.
Common situations: Looking up a child node ID from an old generation of the workflow; offline archive readers using node IDs not present in the (possibly compressed) status; typo'd or fabricated node IDs in custom controllers.
Related errors
- could not find %s in nodes when searching for nested childre
- could not get node status for node ID %s
- can't process Artifact GC Strategy %s: node ID %q not found
- can't process Artifact GC Strategy %s: node %+v has an unnam
- node named %q returned by WorkflowArtifactGCTask %q wasn't f
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/d56ea54e40983c08.
Report an issue: GitHub.