{"record":{"id":"6f68112e6799a74b","repo":"SigNoz/signoz","slug":"agent-updater-is-busy","errorCode":null,"errorMessage":"agent updater is busy","messagePattern":"agent updater is busy","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/query-service/agentConf/manager.go","lineNumber":288,"sourceCode":"\t\t}\n\n\t\topamp.AddToMetricsPipelineSpec(\"filter\")\n\t\tconfigHash, err := opamp.UpsertControlProcessors(ctx, \"metrics\", processorConf, m.OnConfigUpdate)\n\t\tif err != nil {\n\t\t\tslog.ErrorContext(ctx, \"failed to call agent config update for trace processor\", errors.Attr(err))\n\t\t\treturn err\n\t\t}\n\n\t\tm.updateDeployStatus(ctx, orgId, opamptypes.ElementTypeSamplingRules, version, opamptypes.DeployInitiated.StringValue(), \"Deployment started\", configHash, configVersion.Config)\n\t}\n\n\treturn nil\n}\n\n// UpsertFilterProcessor updates the agent config with new filter processor params\nfunc UpsertFilterProcessor(ctx context.Context, orgId valuer.UUID, version int, config *filterprocessor.Config) error {\n\tif !atomic.CompareAndSwapUint32(&m.lock, 0, 1) {\n\t\treturn fmt.Errorf(\"agent updater is busy\")\n\t}\n\tdefer atomic.StoreUint32(&m.lock, 0)\n\n\t// merge current config with new filter params\n\t// merge current config with new filter params\n\tprocessorConf := map[string]interface{}{\n\t\t\"filter\": config,\n\t}\n\n\topamp.AddToMetricsPipelineSpec(\"filter\")\n\tconfigHash, err := opamp.UpsertControlProcessors(ctx, \"metrics\", processorConf, m.OnConfigUpdate)\n\tif err != nil {\n\t\tslog.ErrorContext(ctx, \"failed to call agent config update for trace processor\", errors.Attr(err))\n\t\treturn err\n\t}\n\n\tprocessorConfYaml, yamlErr := yaml.Marshal(config)\n\tif yamlErr != nil {","sourceCodeStart":270,"sourceCodeEnd":306,"githubUrl":"https://github.com/SigNoz/signoz/blob/5069bf80b08f1f00d7e014eccc09902f9871004f/pkg/query-service/agentConf/manager.go#L270-L306","documentation":"UpsertFilterProcessor uses a global atomic lock; if another agent-config update is in flight (lock held), the call returns immediately with 'agent updater is busy'. This is a concurrency guard, not a system failure — only one config mutation runs at a time.","triggerScenarios":"Two overlapping calls to UpsertFilterProcessor (or other mutations sharing m.lock) from concurrent requests or rapid UI updates.","commonSituations":"Bulk automation applying filters concurrently, double-submitted UI forms, or retries racing with a slow in-progress update.","solutions":["Retry after the in-flight update completes (short backoff)","Serialize config-update calls client-side so only one is outstanding","Debounce UI actions that trigger filter upserts"],"exampleFix":"// before\nerr := agentConf.UpsertFilterProcessor(ctx, orgId, version, cfg)\n// after\nvar err error\nfor i := 0; i < 3; i++ {\n    err = agentConf.UpsertFilterProcessor(ctx, orgId, version, cfg)\n    if err == nil || !strings.Contains(err.Error(), \"busy\") {\n        break\n    }\n    time.Sleep(500 * time.Millisecond)\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"Retry with short backoff when the error string contains 'agent updater is busy'; otherwise propagate.","preventionTips":["Serialize agent-config mutations per org","Debounce UI-triggered filter updates","Never fire parallel upserts from automation"],"tags":["concurrency","lock","agent-conf","retryable"],"backgroundTag":"resource-busy-lock","analyzedSha":"5069bf80b08f1f00d7e014eccc09902f9871004f","analyzedAt":"2026-08-28T06:22:12.824Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}