temporalio/temporal · error
failed to read version demotion signal configuration: %w
Error message
failed to read version demotion signal configuration: %w
What it means
shouldUseVersionDemotionSignal reads a MutableSideEffect (versionDemotionSignalMutableSideEffect) to decide whether version demotion must go through a signal. If reading the side-effect value fails, the error is wrapped and propagated to setRamp/handleSetCurrent, blocking the requested ramp or current-version change.
Source
Thrown at service/worker/workerdeployment/workflow.go:140
if workflow.GetVersion(ctx, versionDemotionSignalChangeID, workflow.DefaultVersion, 0) == workflow.DefaultVersion {
// Histories that have commit-routing-first (previous check), but predate this checkpoint are
// workflows that already used signal-based demotion. They must continue
// on the signal path to avoid a non-determinism error, regardless of the
// current dynamic config value.
// OSS 1.31 histories never reach here because they didn't have commit-routing-first.
return true, nil
}
var enabled bool
err := workflow.MutableSideEffect(
ctx,
versionDemotionSignalMutableSideEffect,
func(workflow.Context) any { return versionDemotionSignalEnabledGetter() },
func(a, b any) bool { return a == b },
).Get(&enabled)
if err != nil {
return false, fmt.Errorf("failed to read version demotion signal configuration: %w", err)
}
return enabled, nil
}
func (d *WorkflowRunner) listenToSignals(ctx workflow.Context) {
forceCANSignalChannel := workflow.GetSignalChannel(ctx, ForceCANSignalName)
syncVersionSummaryChannel := workflow.GetSignalChannel(ctx, SyncVersionSummarySignal)
propagationCompleteChannel := workflow.GetSignalChannel(ctx, PropagationCompleteSignal)
d.signalHandler.signalSelector.AddReceive(forceCANSignalChannel, func(c workflow.ReceiveChannel, more bool) {
d.signalHandler.processingSignals++
defer func() { d.signalHandler.processingSignals-- }()
var args *deploymentspb.ForceCANDeploymentSignalArgs
c.Receive(ctx, &args)
d.forceCAN = true
// Apply override state if providedView on GitHub (pinned to bde624efd1)
Solutions
- Check workflow history for the versionDemotionSignal MutableSideEffect record; a missing/corrupt record needs a history-level fix
- Retry the update (SetCurrentVersion/SetRampingVersion) — a fresh workflow execution may recover transient replay issues
- Report with workflow ID/run ID if persistent; mark the deployment series state manually via supported APIs if demotion is blocked
Defensive patterns
Strategy: retry
Try / catch
err := deploymentHandle.SetCurrentVersion(ctx, req)
if err != nil && strings.Contains(err.Error(), "failed to read version demotion signal configuration") {
// transient replay issue — retry the update after backoff
} Prevention
- Avoid server/SDK upgrades that change side-effect formats without testing upgrade on a dev cluster
- Keep deployment update calls idempotent and safe to retry
- If persistent, inspect workflow history for the mutable side-effect record
When it happens
Trigger: workflow.SideEffect/MutableSideEffect Get returning an error, typically deterministic-execution problems, side-effect history corruption, or workflow panic recovery during a SetRampingVersion/SetCurrentVersion update handling.
Common situations: Workflow history replay issues after a server/SDK upgrade; continued-as-new workflows with missing side-effect records; state store corruption.
Related errors
- version cannot be nil on start
- ${failure.Message}
- task queue user data replication failed: %v
- invalid schedule: %s
- WorkflowId or WorkflowType is required in query
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/222fcf46aa65bc10.
Report an issue: GitHub.