{"record":{"id":"8eb0af19ac0d2108","repo":"argoproj/argo-workflows","slug":"invalid-holderkey-format","errorCode":null,"errorMessage":"invalid holderkey format","messagePattern":"invalid holderkey format","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"workflow/sync/sync_manager.go","lineNumber":114,"sourceCode":"\t\tlog:               log,\n\t}\n\tlog.WithField(\"dbConfigured\", sm.dbInfo.SessionProxy != nil).Info(ctx, \"Sync manager initialized\")\n\tsm.dbInfo.Migrate(ctx)\n\n\tif sm.dbInfo.SessionProxy != nil {\n\t\tsm.backgroundNotifier(ctx, config.PollSeconds)\n\t\tsm.dbControllerHeartbeat(ctx, config.HeartbeatSeconds)\n\t}\n\treturn sm\n}\n\nfunc (sm *Manager) getWorkflowKey(key string) (string, error) {\n\tif key == \"\" {\n\t\treturn \"\", fmt.Errorf(\"holderkey is empty\")\n\t}\n\titems := strings.Split(key, \"/\")\n\tif len(items) < 2 {\n\t\treturn \"\", fmt.Errorf(\"invalid holderkey format\")\n\t}\n\treturn fmt.Sprintf(\"%s/%s\", items[0], items[1]), nil\n}\n\nfunc (sm *Manager) CheckWorkflowExistence(ctx context.Context) {\n\tdefer runtimeutil.HandleCrashWithContext(ctx, runtimeutil.PanicHandlers...)\n\n\tsm.lock.Lock()\n\tdefer sm.lock.Unlock()\n\n\tsm.log.Debug(ctx, \"Check the workflow existence\")\n\tfor _, lock := range sm.syncLockMap {\n\t\tholders, err := lock.getCurrentHolders(ctx)\n\t\tif err != nil {\n\t\t\tsm.log.WithError(err).Error(ctx, \"failed to get current lock holders\")\n\t\t\tcontinue\n\t\t}\n\t\tpending, err := lock.getCurrentPending(ctx)","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/workflow/sync/sync_manager.go#L96-L132","documentation":"getWorkflowKey requires at least '<namespace>/<workflow>' in the holder key (split on '/' must yield >= 2 items). A malformed key without a slash cannot be reduced to a workflow identity, so this error is returned from CheckWorkflowExistence's holder scan.","triggerScenarios":"A holder key like 'default-mywf-mynode' or 'mynode' (no '/' separators) is encountered while checking lock holders — e.g. a holder registered with a wrong-format key instead of namespace/workflow/node.","commonSituations":"Custom keys passed to synchronization APIs; state written by a different Argo version with a different holder-key format; manual edits to sync ConfigMaps/DB rows.","solutions":["Locate the malformed holder entry in the lock's holder list (workflow status or sync ConfigMap/DB) and remove or correct it","Re-submit the workflow so holds are re-registered with the canonical 'namespace/workflow/node' format","Verify all controller/CLI components run compatible versions so holder-key formats agree"],"exampleFix":"// before: wrong format\nholderKey := wf.Name\n// after: canonical namespace/workflow/node\nholderKey := fmt.Sprintf(\"%s/%s/%s\", wf.Namespace, wf.Name, nodeName)","handlingStrategy":"validation","validationCode":"func holderKeyFormatOK(key string) bool {\n    parts := strings.Split(key, \"/\")\n    return len(parts) >= 2 && parts[0] != \"\" && parts[1] != \"\"\n}","typeGuard":"func isWellFormedHolderKey(s string) bool {\n    return strings.Count(s, \"/\") >= 1 && !strings.HasPrefix(s, \"/\")\n}","tryCatchPattern":"exists := sm.CheckWorkflowExistence(ctx) // reports holder-key errors\nif err != nil && strings.Contains(err.Error(), \"invalid holderkey format\") {\n    return fmt.Errorf(\"purge malformed holder entry: %w\", err)\n}","preventionTips":["Use the canonical 'namespace/workflow/node' key format everywhere","Clean stale holder entries after version upgrades","Don't invent custom key formats for sync APIs"],"tags":["holder-key","format","sync-manager"],"backgroundTag":"malformed-holder-key","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"}