temporalio/temporal · critical
invalid task schema version
Error message
invalid task schema version
What it means
switchTasksTable translates base Cassandra queries between the tasks and tasks_v2 table schemas based on the matchingTaskVersion. Only matchingTaskVersion1 and matchingTaskVersion2 are supported; any other version is a hard-coded-constant violation and panics. This protects against silently running queries against the wrong schema.
Source
Thrown at common/persistence/cassandra/matching_task_store_queue.go:33
"go.temporal.io/server/common/primitives/timestamp"
)
// matchingTaskVersion represents the task schema version
type matchingTaskVersion int
const (
matchingTaskVersion1 matchingTaskVersion = 1
matchingTaskVersion2 matchingTaskVersion = 2
)
var switchTasksTableV1Cache sync.Map
// switchTasksTable switches table names from tasks to tasks_v2 and modifies queries for v2 schema
func switchTasksTable(baseQuery string, v matchingTaskVersion) string {
if v == matchingTaskVersion2 {
return baseQuery
} else if v != matchingTaskVersion1 {
panic("invalid task schema version") // nolint:forbidigo // hardcoded constants
}
if v1query, ok := switchTasksTableV1Cache.Load(baseQuery); ok {
return v1query.(string) // nolint:revive
}
v1query := strings.ReplaceAll(baseQuery, " tasks_v2 ", " tasks ")
v1query = strings.ReplaceAll(v1query, " AND pass = 0 ", " ")
v1query = strings.ReplaceAll(v1query, "type, pass, task_id", "type, task_id")
v1query = strings.ReplaceAll(v1query, "?, 0, ?", "?, ?")
switchTasksTableV1Cache.Store(baseQuery, v1query)
return v1query
}
// Task queue management queries, written for v2 (rewritten for v1 by switchTasksTable)
const (
templateGetTaskQueueQuery = `SELECT ` +View on GitHub (pinned to bde624efd1)
Solutions
- Verify the matching task schema version in the persistence row/config is 1 or 2
- Run the expected schema migrations (schema dir) so stored data matches the binary's supported versions
- If a third version was added to the codebase, extend switchTasksTable to handle it
- Check for binary/schema version skew during rolling upgrades and align deployment versions
Example fix
// before
} else if v != matchingTaskVersion1 {
panic("invalid task schema version")
}
// after
} else if v != matchingTaskVersion1 {
return nil, serviceerror.NewInternal(fmt.Sprintf("invalid task schema version: %d", v))
} Defensive patterns
Strategy: validation
Validate before calling
if v := queue.GetMatchingTaskVersion(); v != matchingTaskVersion1 && v != matchingTaskVersion2 {
return fmt.Errorf("unsupported matching task schema version: %v", v)
} Prevention
- Keep binary and Cassandra schema versions aligned during rolling upgrades
- Run required schema migrations before deploying new versions
- Never hand-edit matching task rows or version markers in the DB
- Test upgrade/rollback paths that change matchingTaskVersion
When it happens
Trigger: Calling CreateTaskQueue, GetTaskQueue, UpdateTaskQueue, DeleteTaskQueue, or CreateTasks with a persisted task queue/version value that is neither v1 nor v2 — e.g. a corrupted or manually edited tasks row, or a new matchingTaskVersion constant introduced without extending this function.
Common situations: Version skew: persistence data written by a newer/older Temporal version using a different schema version; schema upgrade/rollback in Cassandra leaving rows with unexpected version markers; config pinning an unsupported version.
Related errors
- unable to decode cassandra serial consistency: %v
- cassandra schema version compatibility check failed: %w
- Unknown task category type: %v
- unsupported partition kind:
- corrupted history event batch, wrong version and IDs
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/312f8798ec659af9.
Report an issue: GitHub.