temporalio/temporal · warning

worker deployment version deleted

Error message

worker deployment version deleted

What it means

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.

Source

Thrown at service/worker/workerdeployment/version_workflow.go:1046

			state.RoutingUpdateTime = rg.GetRampingVersionPercentageChangedTime()
		case enumspb.WORKER_DEPLOYMENT_VERSION_STATUS_DRAINING:
			// Version just became draining. So we need to update RoutingUpdateTime which is the max of the following:
			state.RoutingUpdateTime = rg.GetCurrentVersionChangedTime()
			if rg.GetRampingVersionChangedTime().AsTime().After(state.RoutingUpdateTime.AsTime()) {
				state.RoutingUpdateTime = rg.GetRampingVersionChangedTime()
			}
			if rg.GetRampingVersionPercentageChangedTime().AsTime().After(state.RoutingUpdateTime.AsTime()) {
				state.RoutingUpdateTime = rg.GetRampingVersionPercentageChangedTime()
			}
		default: // Shouldn't happen
		}
	}
	return versionDataChanged
}

func (d *VersionWorkflowRunner) handleDescribeQuery() (*deploymentspb.QueryDescribeVersionResponse, error) {
	if d.deleteVersion {
		return nil, errors.New(errVersionDeleted)
	}
	return &deploymentspb.QueryDescribeVersionResponse{
		VersionState: d.VersionState,
	}, nil
}

func (d *VersionWorkflowRunner) newUUID(ctx workflow.Context) string {
	var val string
	_ = workflow.SideEffect(ctx, func(ctx workflow.Context) any {
		return uuid.NewString()
	}).Get(&val)
	return val
}

// Sync version summary with the WorkerDeployment workflow.
func (d *VersionWorkflowRunner) syncSummary(ctx workflow.Context) {
	err := workflow.SignalExternalWorkflow(ctx,
		GenerateDeploymentWorkflowID(d.VersionState.Version.DeploymentName),

View on GitHub (pinned to bde624efd1)

Solutions

  1. Treat this error as 'version already deleted' and stop querying it — the operation effectively succeeded
  2. Check version existence via ListWorkerDeployments/DescribeWorkerDeployment before describing, and handle deletion as an expected state
  3. Avoid describing versions immediately after issuing delete; poll for workflow-completion/eventual visibility removal instead
  4. Use DescribeWorkerDeployment (deployment-level) which lists remaining versions rather than describing a deleted one

Example fix

// before
resp, err := client.DescribeWorkerDeploymentVersion(ctx, "ns", deployment, version)
// after
resp, err := client.DescribeWorkerDeploymentVersion(ctx, "ns", deployment, version)
if err != nil && strings.Contains(err.Error(), "worker deployment version deleted") {
    return nil // already deleted; treat as success
}
Defensive patterns

Strategy: try-catch

Validate before calling

// check the version still exists before describing
resp, err := client.DescribeWorkerDeployment(ctx, ns, deploymentName)
if err == nil {
    var found bool
    for _, v := range resp.GetWorkerDeploymentInfo().GetVersionsSummary() {
        if v.GetVersion() == version { found = true; break }
    }
    if !found { return nil } // already gone
}

Type guard

func isVersionDeletedErr(err error) bool {
    return err != nil && strings.Contains(err.Error(), "worker deployment version deleted")
}

Try / catch

resp, err := client.DescribeWorkerDeploymentVersion(ctx, ns, d, v)
if isVersionDeletedErr(err) {
    return nil // treat as already deleted
}
if err != nil { return err }

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01). Data as JSON: /api/errors/081b7df65545de6c. Report an issue: GitHub.