argoproj/argo-workflows · error

unable to marshal cache entry: %w

Error message

unable to marshal cache entry: %w

What it means

save() marshals the new cache.Entry (nodeID, exit code, timestamps, outputs) to JSON before storing it as a ConfigMap data key. A marshal failure aborts the save with this wrapped error so a half-written entry never reaches the ConfigMap.

Source

Thrown at workflow/controller/cache/configmap_cache.go:195

		if validateErr != nil {
			return validateErr
		}
	}

	creationTime := time.Now()
	cache.SetLabels(map[string]string{common.LabelKeyConfigMapType: common.LabelValueTypeConfigMapCache})

	newEntry := Entry{
		NodeID:            nodeID,
		Outputs:           value,
		CreationTimestamp: metav1.Time{Time: creationTime},
		LastHitTimestamp:  metav1.Time{Time: creationTime},
	}

	entryJSON, err := json.Marshal(newEntry)
	if err != nil {
		c.logError(ctx, err, logging.Fields{"key": key, "nodeID": nodeID}, "Unable to marshal cache entry")
		return fmt.Errorf("unable to marshal cache entry: %w", err)
	}

	if cache.Data == nil {
		cache.Data = make(map[string]string)
	}
	cache.Data[key] = string(entryJSON)

	_, err = c.kubeClient.CoreV1().ConfigMaps(c.namespace).Update(ctx, cache, metav1.UpdateOptions{})
	if err != nil {
		c.logError(ctx, err, logging.Fields{"key": key, "nodeID": nodeID}, "Kubernetes error creating new cache entry")
		return fmt.Errorf("error creating cache entry: %w. Please check out this page for help: https://argo-workflows.readthedocs.io/en/latest/memoization/#faqs", err)
	}
	return nil
}

View on GitHub (pinned to 35bff19146)

Solutions

  1. Re-run the workflow node — memoization will retry the save with a fresh entry.
  2. If on a fork/patch, inspect recent changes to controllercache.Entry for non-JSON-serializable fields and add json tags or remove them.
  3. Delete the memoization ConfigMap entry if a partial write is suspected, then re-execute.
  4. Upgrade to an official Argo release where Entry is fully JSON-serializable.
Defensive patterns

Strategy: try-catch

Try / catch

err := cache.Save(ctx, key, nodeID, entry)
if err != nil && strings.Contains(err.Error(), "unable to marshal cache entry") {
  // serialization failure: treat node as un-memoized and re-run
  return retrySave(ctx, key, nodeID, entry)
}

Prevention

When it happens

Trigger: json.Marshal(newEntry) fails — practically only if Entry carries unserializable data, e.g. via customized/forked Entry structs or invalid field values injected upstream.

Common situations: Custom builds with extended Entry fields (channels, funcs, cyclic refs); otherwise essentially never hit on stock Argo where Entry is all strings and metav1.Time.

Related errors


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