Summary
In managed mode, a principal-initiated sync request can be cleared by an incoming managed-agent status update before the ArgoCD application-controller observes the pending .operation.
The principal UpdateStatus() path previously copied incoming.Operation from the agent status payload directly onto the principal application. Managed-agent status updates often arrive with incoming.Operation == nil, especially immediately after application creation or early reconcile activity. If such a status update lands after the principal sets .operation but before the application-controller acts on it, the sync request is erased.
Impact
- Newly created or recently updated managed applications can remain
OutOfSync / Missing on the principal.
- The sync operation appears to have been requested, but never starts.
- Principal and agent may both end up with no
.operation or .status.operationState, despite the deploy flow having requested a sync.
Environment
- Managed mode
- Principal initiates sync by setting
.operation on Application
- Agent emits early status updates during create/reconcile
- Principal applies managed status updates via
UpdateStatus()
Reproduction
- Create or update an
ApplicationSet targeting managed agents.
- Principal creates the managed
Application.
- Deploy flow or automation sets
.operation on the principal application to trigger sync.
- Before ArgoCD application-controller on the principal processes that operation, the agent emits a status update for the same app.
- Principal handles that managed status update and copies
incoming.Operation == nil over the existing pending operation.
- ArgoCD application-controller never sees a persistent sync request.
Expected Behavior
- Once the principal sets a sync operation, a nil-operation status update from the agent should not clear it.
- Pending sync intent should remain until:
- the agent reports an updated operation payload, or
- ArgoCD application-controller advances the operation state.
Actual Behavior
- Principal application briefly gets
.operation set.
- A managed status update arrives from the agent with
incoming.Operation == nil.
- Principal
UpdateStatus() clears the existing .operation.
- The sync operation never starts.
- Principal and agent can both end up with:
- no
.operation
- no
.status.operationState
- app still
OutOfSync / Missing
Evidence / Symptoms
Typical symptoms observed:
- deploy flow requested sync
- principal app later has no
.operation
- principal
argocd-application-controller logs show no sync start for the affected app
- agent status traffic appears immediately after create
- app remains unsynced until another change re-triggers progress
Suspected Root Cause
In principal managed-mode UpdateStatus(), the code used to do:
existing.Operation = incoming.Operation
- patch target
Operation: incoming.Operation
When incoming.Operation == nil, that unconditionally removed any existing pending operation from the principal application.
This makes managed status updates race with sync initiation.
Relevant Code
internal/manager/application/application.go
- principal
UpdateStatus() path
- Managed status updates often omit
.operation
- Principal sync initiation relies on
.operation remaining present long enough for ArgoCD application-controller to act on it
Why This Is Separate From #840
This issue is about the principal clearing .operation after receiving a managed status update.
A separate issue exists where sync-carrying SpecUpdate events can be coalesced away before reaching the agent.
Proposed Fix
Preserve an existing operation when the incoming managed status update has incoming.Operation == nil.
reuse the same helper logic already used elsewhere for operation preservation:
- preserve existing operation if incoming operation is nil
- continue to honor explicit incoming operation updates
- keep terminating-operation behavior intact
Summary
In managed mode, a principal-initiated sync request can be cleared by an incoming managed-agent status update before the ArgoCD application-controller observes the pending
.operation.The principal
UpdateStatus()path previously copiedincoming.Operationfrom the agent status payload directly onto the principal application. Managed-agent status updates often arrive withincoming.Operation == nil, especially immediately after application creation or early reconcile activity. If such a status update lands after the principal sets.operationbut before the application-controller acts on it, the sync request is erased.Impact
OutOfSync/Missingon the principal..operationor.status.operationState, despite the deploy flow having requested a sync.Environment
.operationonApplicationUpdateStatus()Reproduction
ApplicationSettargeting managed agents.Application..operationon the principal application to trigger sync.incoming.Operation == nilover the existing pending operation.Expected Behavior
Actual Behavior
.operationset.incoming.Operation == nil.UpdateStatus()clears the existing.operation..operation.status.operationStateOutOfSync/MissingEvidence / Symptoms
Typical symptoms observed:
.operationargocd-application-controllerlogs show no sync start for the affected appSuspected Root Cause
In principal managed-mode
UpdateStatus(), the code used to do:existing.Operation = incoming.OperationOperation: incoming.OperationWhen
incoming.Operation == nil, that unconditionally removed any existing pending operation from the principal application.This makes managed status updates race with sync initiation.
Relevant Code
internal/manager/application/application.goUpdateStatus()path.operation.operationremaining present long enough for ArgoCD application-controller to act on itWhy This Is Separate From #840
This issue is about the principal clearing
.operationafter receiving a managed status update.A separate issue exists where sync-carrying
SpecUpdateevents can be coalesced away before reaching the agent.Proposed Fix
Preserve an existing operation when the incoming managed status update has
incoming.Operation == nil.reuse the same helper logic already used elsewhere for operation preservation: