{"record":{"id":"9f94c6cd00c107cf","repo":"argoproj/argo-workflows","slug":"synchronization-database-session-is-not-available","errorCode":null,"errorMessage":"synchronization database session is not available","messagePattern":"synchronization database session is not available","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"workflow/sync/sync_manager.go","lineNumber":484,"sourceCode":"\tfor i, syncItem := range syncItems {\n\t\tsyncLockName, lockNameErr := syncItem.lockName(wf.Namespace)\n\t\tif lockNameErr != nil {\n\t\t\treturn false, false, \"\", failedLockName, fmt.Errorf(\"requested configuration is invalid: %w\", lockNameErr)\n\t\t}\n\t\tsm.log.WithField(\"syncLockName\", syncLockName).Info(ctx, \"TryAcquire\")\n\t\tlockKeys[i] = syncLockName.String(ctx)\n\t}\n\n\tif ok, msg, prepLockName, prepErr := sm.prepAcquire(ctx, wf, holderKey, syncItems, lockKeys); !ok {\n\t\treturn false, false, msg, prepLockName, prepErr\n\t}\n\n\tneedDB, err := needDBSession(ctx, lockKeys)\n\tif err != nil {\n\t\treturn false, false, \"\", failedLockName, fmt.Errorf(\"couldn't decode locks for session: %w\", err)\n\t}\n\tif needDB && sm.dbInfo.SessionProxy == nil {\n\t\treturn false, false, \"\", failedLockName, fmt.Errorf(\"synchronization database session is not available\")\n\t}\n\tif needDB {\n\t\tvar updated bool\n\t\tvar already bool\n\t\tvar msg string\n\t\tvar newly []*acquiredLock\n\t\tbackoff := dbRetryBackoff\n\t\t// tryAcquireImpl mutates wf.Status.Synchronization in memory before the\n\t\t// transaction commits. Snapshot it and roll each failed attempt back, so\n\t\t// that attempts are independent and an error return leaves the caller's\n\t\t// status exactly as it was - otherwise an abort leaves a Holding entry\n\t\t// for a row the database rolled back, which would be persisted and then\n\t\t// failed as a stale hold on the next controller restart.\n\t\tsyncStatus := wf.Status.Synchronization.DeepCopy()\n\t\tattempt := 0\n\t\terr = retry.OnError(backoff, IsRetryableSyncError, func() error {\n\t\t\tattempt++\n\t\t\tsm.log.WithFields(logging.Fields{","sourceCodeStart":466,"sourceCodeEnd":502,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/workflow/sync/sync_manager.go#L466-L502","documentation":"One of the lock keys requires a database-backed semaphore, but the Manager was built without a DB session proxy (dbInfo.SessionProxy == nil). Without the session the manager cannot read or update DB lock state, so acquisition is refused rather than silently bypassing the DB lock.","triggerScenarios":"A workflow uses a database-sourced semaphore (sync config in Postgres/MySQL) while the controller runs without synchronization DB persistence configured or the session is unavailable at runtime.","commonSituations":"Controller installed with persistence disabled while workflows reference DB-backed sync; wrong DB credentials so SessionProxy was never created; DB lost after startup.","solutions":["Enable and configure synchronization DB persistence in the controller config","Point the controller at the correct Postgres/MySQL instance used for sync state","Restart the controller so the session proxy is initialized","Switch the workflow to ConfigMap-based synchronization if no DB is intended"],"exampleFix":"// before (controller config)\n# no sync database configured\n// after\nsyncDatabase:\n  postgresql:\n    host: postgres\n    port: 5432\n    database: argo_sync","handlingStrategy":"validation","validationCode":"if needsDB(lockKeys) && manager.SessionProxy == nil {\n    return errors.New(\"configure sync DB persistence before using DB-backed semaphores\")\n}","typeGuard":"func dbSessionReady(sm *sync.Manager) bool { return sm != nil && sm.DBInfo != nil && sm.DBInfo.SessionProxy != nil }","tryCatchPattern":"if _, _, _, _, err := sm.TryAcquire(...); err != nil && strings.Contains(err.Error(), \"database session is not available\") { /* alert: persistence misconfigured */ }","preventionTips":["Verify persistence settings in controller startup health checks","Document DB requirements for DB-backed semaphores","Alert on 'synchronization database session is not available' occurrences"],"tags":["argo-workflows","sync","database","configuration","persistence"],"backgroundTag":"missing-database-session","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"}