argoproj/argo-workflows · error
duplicate synchronization item found
Error message
duplicate synchronization item found
What it means
When a workflow declares its synchronization section, Argo collects all sync items (semaphores and mutexes) and checks for duplicates with reflect.DeepEqual. If two entries in the list are exactly identical — same type, same namespace, name and key — the configuration is rejected as ambiguous, because the workflow would wait on the same lock twice. Note this error is created with errors.New without a code (plain error, not a coded ArgoError).
Source
Thrown at workflow/sync/syncitems.go:30
mutex *v1alpha1.Mutex
}
func allSyncItems(sync *v1alpha1.Synchronization) ([]*syncItem, error) {
var syncItems []*syncItem
for _, semaphore := range sync.Semaphores {
syncItems = append(syncItems, &syncItem{semaphore: semaphore})
}
for _, mtx := range sync.Mutexes {
syncItems = append(syncItems, &syncItem{mutex: mtx})
}
return syncItems, checkDuplicates(syncItems)
}
func checkDuplicates(items []*syncItem) error {
for i, item := range items {
for j := i + 1; j < len(items); j++ {
if reflect.DeepEqual(*item, *items[j]) {
return errors.New("duplicate synchronization item found")
}
}
}
return nil
}
func (i *syncItem) getType() v1alpha1.SynchronizationType {
switch {
case i.semaphore != nil:
return v1alpha1.SynchronizationTypeSemaphore
case i.mutex != nil:
return v1alpha1.SynchronizationTypeMutex
default:
return v1alpha1.SynchronizationTypeUnknown
}
}
View on GitHub (pinned to 35bff19146)
Solutions
- Deduplicate spec.synchronization: keep one entry per unique semaphore/mutex in the workflow YAML
- Search the rendered/templated manifest for repeated blocks (e.g. `grep -n "configMapKeyRef\|mutex"`) and merge them
- If duplicates come from overlays/patches, move the synchronization section to the base or use a single source of truth
Example fix
# before
synchronization:
mutexes:
- name: my-mutex
- name: my-mutex
# after
synchronization:
mutexes:
- name: my-mutex Defensive patterns
Strategy: validation
Validate before calling
seen := map[string]bool{}
for _, m := range wf.Spec.Synchronization.Mutexes {
if seen[m.Name] { return fmt.Errorf("duplicate mutex %s", m.Name) }
seen[m.Name] = true
} Type guard
func hasDuplicateSyncItems(items []v1alpha1.SemaphoreRef) bool {
seen := map[string]bool{}
for _, it := range items {
k := fmt.Sprintf("%v", it)
if seen[k] { return true }
seen[k] = true
}
return false
} Try / catch
if err := wfv1.Validate(wf); err != nil {
return fmt.Errorf("workflow spec rejected: %w", err) // surfaces duplicate synchronization item found
} Prevention
- Keep at most one entry per unique semaphore/mutex under spec.synchronization
- Deduplicate after any Helm/Kustomize templating before argo submit
- Review rendered YAML with grep for repeated synchronization blocks
When it happens
Trigger: Submitting or linting a workflow whose spec.synchronization contains two identical semaphore or mutex entries (e.g. the same configMapKeyRef name+key listed twice, or the same mutex twice). Raised from checkDuplicates, called by allSyncItems when building the sync items list.
Common situations: Copy-pasting a semaphore block within the same synchronization section; merging YAML fragments (e.g. via Kustomize patches or CI templating) that duplicate an entry; programmatically appending sync items without deduplication.
Related errors
- CodeBadRequest
- failed to parse YAML from file %s: %w
- containers must have at least one container
- malformed workflow template parameter "%s": valueFrom is nil
- no text to unmarshal
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/45632516d937da7b.
Report an issue: GitHub.