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

  1. Verify the nodeID exists with Nodes.Has(nodeID) before calling Get
  2. Re-fetch/hydrate the Workflow object — node status may be offloaded or from a stale copy
  3. 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

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


AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03). Data as JSON: /api/errors/d56ea54e40983c08. Report an issue: GitHub.