temporalio/temporal · error
unknown transaction policy: %v
Error message
unknown transaction policy: %v
What it means
During mutable-state task generation, code that applies a historyi.TransactionPolicy switches over the policy value (Active, Passive, ...) and panics on anything else with "unknown transaction policy: %v". TransactionPolicy tells the history service whether this node is the active cluster (should emit tasks/replication) or passive. A value outside the known set means a new enum member was added without updating this switch, or the policy was constructed incorrectly.
Source
Thrown at service/history/workflow/mutable_state_impl.go:8467
NextEventID: nextEventID,
TaskEquivalents: replicationTasks,
LastVersionHistoryItem: lastVersionHistoryItem,
}
if ms.dbRecordVersion == 1 {
syncVersionedTransitionTask.IsFirstTask = true
}
// versioned transition updated in the transaction
ms.InsertTasks[tasks.CategoryReplication] = append(
ms.InsertTasks[tasks.CategoryReplication],
syncVersionedTransitionTask,
)
}
}
case historyi.TransactionPolicyPassive:
default:
panic(fmt.Sprintf("unknown transaction policy: %v", transactionPolicy))
}
} else if isWorkflow {
ms.InsertTasks[tasks.CategoryReplication] = append(
ms.InsertTasks[tasks.CategoryReplication],
replicationTasks...,
)
} else {
return softassert.UnexpectedInternalErr(ms.logger, "state-based replication not enabled for chasm execution", nil)
}
if transactionPolicy == historyi.TransactionPolicyPassive &&
len(ms.InsertTasks[tasks.CategoryReplication]) > 0 {
return softassert.UnexpectedInternalErr(
ms.logger,
"should not generate replication task when close transaction as passive",
nil,
)
}View on GitHub (pinned to bde624efd1)
Solutions
- Upgrade all history service binaries to the same version so every TransactionPolicy value is handled everywhere.
- Search the codebase for the new TransactionPolicy constant and add the missing case to this switch.
- Audit the caller that passed the policy value to confirm it isn't passing an uninitialized/zero-value policy.
- If it reproduces on a single version, file a bug with the printed policy value.
Example fix
// before
case historyi.TransactionPolicyPassive:
default:
panic(fmt.Sprintf("unknown transaction policy: %v", transactionPolicy))
// after
case historyi.TransactionPolicyPassive:
case historyi.TransactionPolicyActive: // handle new value explicitly
default:
panic(fmt.Sprintf("unknown transaction policy: %v", transactionPolicy)) Defensive patterns
Strategy: validation
Validate before calling
// Before invoking task generation, assert the policy is one of the known values:
if transactionPolicy != historyi.TransactionPolicyActive &&
transactionPolicy != historyi.TransactionPolicyPassive {
return fmt.Errorf("unrecognized transaction policy %v", transactionPolicy)
} Type guard
func knownTransactionPolicy(p historyi.TransactionPolicy) bool {
switch p {
case historyi.TransactionPolicyActive, historyi.TransactionPolicyPassive:
return true
}
return false
} Prevention
- Run identical server versions on all history nodes.
- When adding a TransactionPolicy constant, update every switch in mutable_state_impl.go in the same PR.
- Never construct TransactionPolicy from raw integers.
- Keep unit tests that exhaustively enumerate TransactionPolicy values across all switch sites.
When it happens
Trigger: Generating replication tasks inside an HSM/transaction update path (around line 8467) when the transactionPolicy parameter holds an unrecognized value — e.g. a newly added TransactionPolicy constant not yet handled in this switch, or a policy passed through from an incompatible caller.
Common situations: Version skew where one binary produces a new policy value another binary's switch doesn't handle; internal refactoring bugs adding a new policy without updating all switches.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Current cluster name is empty
- Version increment <= 0 or > 2147483647
- <dynamic updateVersionToClusterName err>
- Current cluster is not specified in cluster info
- Master cluster is not specified in cluster info
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/d93c33d87a187aeb.
Report an issue: GitHub.