{"record":{"id":"081b7df65545de6c","repo":"temporalio/temporal","slug":"worker-deployment-version-deleted","errorCode":null,"errorMessage":"worker deployment version deleted","messagePattern":"worker deployment version deleted","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"service/worker/workerdeployment/version_workflow.go","lineNumber":1046,"sourceCode":"\t\t\tstate.RoutingUpdateTime = rg.GetRampingVersionPercentageChangedTime()\n\t\tcase enumspb.WORKER_DEPLOYMENT_VERSION_STATUS_DRAINING:\n\t\t\t// Version just became draining. So we need to update RoutingUpdateTime which is the max of the following:\n\t\t\tstate.RoutingUpdateTime = rg.GetCurrentVersionChangedTime()\n\t\t\tif rg.GetRampingVersionChangedTime().AsTime().After(state.RoutingUpdateTime.AsTime()) {\n\t\t\t\tstate.RoutingUpdateTime = rg.GetRampingVersionChangedTime()\n\t\t\t}\n\t\t\tif rg.GetRampingVersionPercentageChangedTime().AsTime().After(state.RoutingUpdateTime.AsTime()) {\n\t\t\t\tstate.RoutingUpdateTime = rg.GetRampingVersionPercentageChangedTime()\n\t\t\t}\n\t\tdefault: // Shouldn't happen\n\t\t}\n\t}\n\treturn versionDataChanged\n}\n\nfunc (d *VersionWorkflowRunner) handleDescribeQuery() (*deploymentspb.QueryDescribeVersionResponse, error) {\n\tif d.deleteVersion {\n\t\treturn nil, errors.New(errVersionDeleted)\n\t}\n\treturn &deploymentspb.QueryDescribeVersionResponse{\n\t\tVersionState: d.VersionState,\n\t}, nil\n}\n\nfunc (d *VersionWorkflowRunner) newUUID(ctx workflow.Context) string {\n\tvar val string\n\t_ = workflow.SideEffect(ctx, func(ctx workflow.Context) any {\n\t\treturn uuid.NewString()\n\t}).Get(&val)\n\treturn val\n}\n\n// Sync version summary with the WorkerDeployment workflow.\nfunc (d *VersionWorkflowRunner) syncSummary(ctx workflow.Context) {\n\terr := workflow.SignalExternalWorkflow(ctx,\n\t\tGenerateDeploymentWorkflowID(d.VersionState.Version.DeploymentName),","sourceCodeStart":1028,"sourceCodeEnd":1064,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/service/worker/workerdeployment/version_workflow.go#L1028-L1064","documentation":"handleDescribeQuery serves the DescribeVersion query on a Worker Deployment Version workflow. Once the version has been deleted, the workflow keeps running (as a zombie draining state) but can no longer answer describe queries, so it returns errVersionDeleted. Callers see this as a query failure meaning the version no longer exists.","triggerScenarios":"Issuing DescribeWorkerDeploymentVersion (or any SDK/CLI describe of a deployment version) while the version workflow is in the deleted state — i.e. after DeleteWorkerDeploymentVersion succeeded but before the workflow fully stops.","commonSituations":"CLI/scripts racing a delete with a describe; dashboards polling version state after deletion; retry logic that re-describes a version right after issuing delete; eventual-consistency windows where the workflow record still exists.","solutions":["Treat this error as 'version already deleted' and stop querying it — the operation effectively succeeded","Check version existence via ListWorkerDeployments/DescribeWorkerDeployment before describing, and handle deletion as an expected state","Avoid describing versions immediately after issuing delete; poll for workflow-completion/eventual visibility removal instead","Use DescribeWorkerDeployment (deployment-level) which lists remaining versions rather than describing a deleted one"],"exampleFix":"// before\nresp, err := client.DescribeWorkerDeploymentVersion(ctx, \"ns\", deployment, version)\n// after\nresp, err := client.DescribeWorkerDeploymentVersion(ctx, \"ns\", deployment, version)\nif err != nil && strings.Contains(err.Error(), \"worker deployment version deleted\") {\n    return nil // already deleted; treat as success\n}","handlingStrategy":"try-catch","validationCode":"// check the version still exists before describing\nresp, err := client.DescribeWorkerDeployment(ctx, ns, deploymentName)\nif err == nil {\n    var found bool\n    for _, v := range resp.GetWorkerDeploymentInfo().GetVersionsSummary() {\n        if v.GetVersion() == version { found = true; break }\n    }\n    if !found { return nil } // already gone\n}","typeGuard":"func isVersionDeletedErr(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"worker deployment version deleted\")\n}","tryCatchPattern":"resp, err := client.DescribeWorkerDeploymentVersion(ctx, ns, d, v)\nif isVersionDeletedErr(err) {\n    return nil // treat as already deleted\n}\nif err != nil { return err }","preventionTips":["Don't describe a version immediately after issuing delete; poll for eventual removal","Design delete-then-verify flows to accept this error as success","Track deletions in automation state so describe loops skip deleted versions"],"tags":["worker-deployments","query","deleted-version","temporal"],"backgroundTag":"entity-already-deleted","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}