{"record":{"id":"ef4b66c6c3379d1a","repo":"argoproj/argo-workflows","slug":"unable-to-marshal-cache-entry-with-last-hit-timest","errorCode":null,"errorMessage":"unable to marshal cache entry with last hit timestamp: %w","messagePattern":"unable to marshal cache entry with last hit timestamp: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"workflow/controller/cache/configmap_cache.go","lineNumber":124,"sourceCode":"\tc.logInfo(ctx, logging.Fields{}, \"config map cache loaded\")\n\thitTime := time.Now()\n\trawEntry, ok := cm.Data[key]\n\tif !ok || rawEntry == \"\" {\n\t\tc.logInfo(ctx, logging.Fields{}, \"config map cache miss: entry does not exist\")\n\t\treturn nil, nil\n\t}\n\n\tvar entry Entry\n\terr = json.Unmarshal([]byte(rawEntry), &entry)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"malformed cache entry: could not unmarshal JSON; unable to parse: %w\", err)\n\t}\n\n\tentry.LastHitTimestamp = metav1.Time{Time: hitTime}\n\tentryJSON, err := json.Marshal(entry)\n\tif err != nil {\n\t\tc.logError(ctx, err, logging.Fields{\"key\": key}, \"Unable to marshal cache entry with last hit timestamp\")\n\t\treturn nil, fmt.Errorf(\"unable to marshal cache entry with last hit timestamp: %w\", err)\n\t}\n\tcm.Data[key] = string(entryJSON)\n\n\t_, err = c.kubeClient.CoreV1().ConfigMaps(c.namespace).Update(ctx, cm, metav1.UpdateOptions{})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &entry, nil\n}\n\nfunc (c *configMapCache) Save(ctx context.Context, key string, nodeID string, value *wfv1.Outputs) error {\n\terr := retry.OnError(kwait.Backoff{\n\t\tDuration: time.Second,\n\t\tFactor:   2,\n\t\tJitter:   0.1,\n\t\tSteps:    5,\n\t\tCap:      30 * time.Second,\n\t}, func(err error) bool {","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/workflow/controller/cache/configmap_cache.go#L106-L142","documentation":"After a cache hit, load() updates the entry's LastHitTimestamp and re-marshals the Entry back to JSON before writing it to the ConfigMap. json.Marshal of a populated Entry essentially never fails in practice; if it does, the load is aborted with this wrapped error rather than returning a corrupted cache entry.","triggerScenarios":"json.Marshal(entry) returning an error after setting LastHitTimestamp — theoretically only via unsupported field states (e.g. a corrupted time value in the entry being re-serialized).","commonSituations":"Practically unreachable for well-formed entries; seen only when Entry struct gains a field whose serialization fails or when upstream code injects an Entry with unserializable data in a fork/patch.","solutions":["Retry the memoization lookup — transient; a fresh entry will be re-created on re-execution.","Delete the offending ConfigMap key so the node re-executes and saves a clean entry.","If running a patched/forked controller, review recent changes to cache.Entry for fields that json.Marshal cannot serialize (channels, funcs, cycles).","Upgrade to a released Argo version — stock Entry (all strings/timestamps) always marshals."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"entry, err := cache.Load(ctx, key)\nif err != nil {\n  if strings.Contains(err.Error(), \"unable to marshal cache entry\") {\n    // transient/serialization issue: treat as miss and retry once\n    entry, err = cache.Load(ctx, key)\n  }\n  if err != nil { return err }\n}","preventionTips":["Keep cache.Entry JSON-serializable if forking/extending the controller.","On repeated failures, delete the ConfigMap key and let memoization rebuild the entry.","Report persistent occurrences upstream — stock Entry cannot trigger this.","Treat as a cache miss rather than a hard failure in wrappers around Load."],"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"}