argoproj/argo-workflows · error
cannot get LockName for a Semaphore without a ConfigMapRef o
Error message
cannot get LockName for a Semaphore without a ConfigMapRef or Database
What it means
getSemaphoreLockName reached its default branch: the SemaphoreRef has neither ConfigMapKeyRef nor Database set, so no lock identity can be derived. The controller cannot track or acquire a semaphore that names no backend.
Source
Thrown at workflow/sync/lock_name.go:69
func getSemaphoreLockName(sem *v1alpha1.SemaphoreRef, wfNamespace string) (*lockName, error) {
switch {
case sem.ConfigMapKeyRef != nil && sem.Database != nil:
return nil, fmt.Errorf("invalid semaphore with both ConfigMapKeyRef and Database")
case sem.ConfigMapKeyRef != nil:
namespace := sem.Namespace
if namespace == "" {
namespace = wfNamespace
}
return newLockName(namespace, sem.ConfigMapKeyRef.Name, sem.ConfigMapKeyRef.Key, lockKindConfigMap), nil
case sem.Database != nil:
namespace := sem.Namespace
if namespace == "" {
namespace = wfNamespace
}
return newLockName(namespace, sem.Database.Key, "", lockKindDatabase), nil
default:
return nil, fmt.Errorf("cannot get LockName for a Semaphore without a ConfigMapRef or Database")
}
}
func getMutexLockName(mtx *v1alpha1.Mutex, wfNamespace string) *lockName {
namespace := mtx.Namespace
if namespace == "" {
namespace = wfNamespace
}
if mtx.Database {
return newLockName(namespace, mtx.Name, "", lockKindDatabase)
}
return newLockName(namespace, mtx.Name, "", lockKindMutex)
}
func (i *syncItem) lockName(wfNamespace string) (*lockName, error) {
switch {
case i.semaphore != nil:
return getSemaphoreLockName(i.semaphore, wfNamespace)View on GitHub (pinned to 35bff19146)
Solutions
- Set either `configMapKeyRef` (name+key) or `database` (key) on the semaphore
- Lint with `argo lint` before submitting to catch the empty ref
- Inspect the submitted workflow spec (`argo get <wf> -o yaml`) to see what actually rendered
Example fix
// before
synchronization:
semaphore: {}
// after
synchronization:
semaphore:
configMapKeyRef:
name: my-cm
key: my-key Defensive patterns
Strategy: validation
Validate before calling
func validateSemaphoreRef(sem *SemaphoreRef) error {
if sem == nil || (sem.ConfigMapKeyRef == nil && sem.Database == nil) {
return fmt.Errorf("semaphore requires configMapKeyRef or database")
}
return nil
} Type guard
func semaphoreRefHasBackend(sem *SemaphoreRef) bool {
return sem != nil && (sem.ConfigMapKeyRef != nil || sem.Database != nil)
} Try / catch
err := wf.Submit(ctx)
if err != nil && strings.Contains(err.Error(), "without a ConfigMapRef or Database") {
return fmt.Errorf("populate the semaphore ref in the spec: %w", err)
} Prevention
- Lint templates after any templating/substitution that could leave fields empty
- Check rendered output (`argo get -o yaml`) when using Helm/Kustomize to inject sync config
- Never hand-write `semaphore: {}` placeholders
When it happens
Trigger: A workflow declares `synchronization.semaphore: {}` (empty object) or a rendered template resolves the semaphore ref to nil fields; getSemaphoreLockName falls through to default.
Common situations: Partial template substitution leaving the semaphore block empty; YAML mistakes like a mis-indented configMapKeyRef so it parses as a sibling key; programmatically constructed workflow specs with unset fields.
Related errors
- invalid semaphore with both ConfigMapKeyRef and Database
- malformed workflow template parameter "%s": valueFrom is nil
- maxRetries cannot be less than 0
- baseDelay cannot be less than 0
- maxDelay cannot be less than 0
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/f0a97b584f22161e.
Report an issue: GitHub.