{"record":{"id":"11e920a6772f540f","repo":"argoproj/argo-workflows","slug":"unable-to-marshal-cache-entry-w","errorCode":null,"errorMessage":"unable to marshal cache entry: %w","messagePattern":"unable to marshal cache entry: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"workflow/controller/cache/configmap_cache.go","lineNumber":195,"sourceCode":"\t\tif validateErr != nil {\n\t\t\treturn validateErr\n\t\t}\n\t}\n\n\tcreationTime := time.Now()\n\tcache.SetLabels(map[string]string{common.LabelKeyConfigMapType: common.LabelValueTypeConfigMapCache})\n\n\tnewEntry := Entry{\n\t\tNodeID:            nodeID,\n\t\tOutputs:           value,\n\t\tCreationTimestamp: metav1.Time{Time: creationTime},\n\t\tLastHitTimestamp:  metav1.Time{Time: creationTime},\n\t}\n\n\tentryJSON, err := json.Marshal(newEntry)\n\tif err != nil {\n\t\tc.logError(ctx, err, logging.Fields{\"key\": key, \"nodeID\": nodeID}, \"Unable to marshal cache entry\")\n\t\treturn fmt.Errorf(\"unable to marshal cache entry: %w\", err)\n\t}\n\n\tif cache.Data == nil {\n\t\tcache.Data = make(map[string]string)\n\t}\n\tcache.Data[key] = string(entryJSON)\n\n\t_, err = c.kubeClient.CoreV1().ConfigMaps(c.namespace).Update(ctx, cache, metav1.UpdateOptions{})\n\tif err != nil {\n\t\tc.logError(ctx, err, logging.Fields{\"key\": key, \"nodeID\": nodeID}, \"Kubernetes error creating new cache entry\")\n\t\treturn fmt.Errorf(\"error creating cache entry: %w. Please check out this page for help: https://argo-workflows.readthedocs.io/en/latest/memoization/#faqs\", err)\n\t}\n\treturn nil\n}\n","sourceCodeStart":177,"sourceCodeEnd":210,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/workflow/controller/cache/configmap_cache.go#L177-L210","documentation":"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.","triggerScenarios":"json.Marshal(newEntry) fails — practically only if Entry carries unserializable data, e.g. via customized/forked Entry structs or invalid field values injected upstream.","commonSituations":"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.","solutions":["Re-run the workflow node — memoization will retry the save with a fresh entry.","If on a fork/patch, inspect recent changes to controllercache.Entry for non-JSON-serializable fields and add json tags or remove them.","Delete the memoization ConfigMap entry if a partial write is suspected, then re-execute.","Upgrade to an official Argo release where Entry is fully JSON-serializable."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"err := cache.Save(ctx, key, nodeID, entry)\nif err != nil && strings.Contains(err.Error(), \"unable to marshal cache entry\") {\n  // serialization failure: treat node as un-memoized and re-run\n  return retrySave(ctx, key, nodeID, entry)\n}","preventionTips":["Avoid adding non-JSON-serializable fields to cache.Entry in forks.","Re-run the node after this error — a fresh entry normally marshals fine.","Keep on upstream Argo releases where Entry is plain strings + metav1.Time.","Log the full wrapped error to capture the underlying marshal cause."],"tags":["memoization","cache","serialization"],"backgroundTag":"cache-marshal-failure","analyzedSha":"35bff19146f5a6ada77468c431f2624bd577e373","analyzedAt":"2026-09-03T19:34:35.908Z","contentChangedAt":"2026-09-03T19:34:35.908Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}