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

  1. Verify the matching task schema version in the persistence row/config is 1 or 2
  2. Run the expected schema migrations (schema dir) so stored data matches the binary's supported versions
  3. If a third version was added to the codebase, extend switchTasksTable to handle it
  4. 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

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


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