temporalio/temporal · error
unknown persistence task predicate type: %v
Error message
unknown persistence task predicate type: %v
What it means
FromPersistencePredicate is the inverse of ToPersistencePredicate: it maps a persistencespb.Predicate back to a tasks.Predicate by predicate type enum. The default branch panics when the stored PREDICATE_TYPE value has no known deserializer.
Source
Thrown at service/history/queues/convert.go:157
return FromPersistenceEmptyPredicate(predicate.GetEmptyPredicateAttributes())
case enumsspb.PREDICATE_TYPE_AND:
return FromPersistenceAndPredicate(predicate.GetAndPredicateAttributes())
case enumsspb.PREDICATE_TYPE_OR:
return FromPersistenceOrPredicate(predicate.GetOrPredicateAttributes())
case enumsspb.PREDICATE_TYPE_NOT:
return FromPersistenceNotPredicate(predicate.GetNotPredicateAttributes())
case enumsspb.PREDICATE_TYPE_NAMESPACE_ID:
return FromPersistenceNamespaceIDPredicate(predicate.GetNamespaceIdPredicateAttributes())
case enumsspb.PREDICATE_TYPE_TASK_TYPE:
return FromPersistenceTaskTypePredicate(predicate.GetTaskTypePredicateAttributes())
case enumsspb.PREDICATE_TYPE_DESTINATION:
return FromPersistenceDestinationPredicate(predicate.GetDestinationPredicateAttributes())
case enumsspb.PREDICATE_TYPE_OUTBOUND_TASK_GROUP:
return FromPersistenceOutboundTaskGroupPredicate(predicate.GetOutboundTaskGroupPredicateAttributes())
case enumsspb.PREDICATE_TYPE_OUTBOUND_TASK:
return FromPersistenceOutboundTaskPredicate(predicate.GetOutboundTaskPredicateAttributes())
default:
panic(fmt.Sprintf("unknown persistence task predicate type: %v", predicate.GetPredicateType()))
}
}
func ToPersistenceUniversalPredicate(
_ *predicates.UniversalImpl[tasks.Task],
) *persistencespb.Predicate {
return &persistencespb.Predicate{
PredicateType: enumsspb.PREDICATE_TYPE_UNIVERSAL,
Attributes: &persistencespb.Predicate_UniversalPredicateAttributes{},
}
}
func FromPersistenceUniversalPredicate(
_ *persistencespb.UniversalPredicateAttributes,
) tasks.Predicate {
return predicates.Universal[tasks.Task]()
}
View on GitHub (pinned to bde624efd1)
Solutions
- Upgrade the service version so it recognizes the persisted PREDICATE_TYPE
- Add the missing enumsspb.PREDICATE_TYPE case mapping to a FromPersistence... function and regenerate code
- Inspect the offending persistence record; if corrupt, delete/rewrite it so the default predicate (ALL) is used
- Ensure proto-generated code is up to date (make proto / make update-go-api) so enum values match
Example fix
// before
default:
panic(fmt.Sprintf("unknown persistence task predicate type: %v", predicate.GetPredicateType()))
// after
case enumsspb.PREDICATE_TYPE_MY_NEW:
return FromPersistenceMyNewPredicate(predicate.GetMyNewPredicateAttributes())
default:
return predicates.EmptyTaskPredicate(), nil // or log + fall back Defensive patterns
Strategy: validation
Validate before calling
if p.GetPredicateType() == enumsspb.PREDICATE_TYPE_UNSPECIFIED ||
!knownPredicateTypes[p.GetPredicateType()] {
// fall back to empty/ALL predicate instead of deserializing
return predicates.EmptyTaskPredicate()
} Try / catch
func safeFromPersistence(p *persistencespb.Predicate) (out tasks.Predicate) {
defer func() {
if r := recover(); r != nil {
out = predicates.EmptyTaskPredicate()
}
}()
out = queues.FromPersistencePredicate(p)
return
} Prevention
- Keep service versions homogeneous across the cluster during upgrades
- Add a coverage test for every enumsspb.PREDICATE_TYPE value
- Regenerate proto code after enum changes (make proto / make update-go-api)
- Treat UNSPECIFIED predicate types defensively when reading persistence records
When it happens
Trigger: Reading a predicate blob from persistence (e.g. task queue metadata / rate limiter scope) whose PREDICATE_TYPE was written by a newer or patched temporal version, is zero/unset, or is corrupt.
Common situations: Rolling upgrades or downgrades where a new predicate type was persisted by newer code and read by older code; corrupted or hand-edited persistence rows; enums added to proto but converter not regenerated.
Related errors
- Found key with non-zero pending task count but has no corres
- unknown task predicate type: %T
- panic(e)
- Iterator encountered Next call when there is no next item
- Unable to split iterator with range %v at %v
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/90efeb82620b71b9.
Report an issue: GitHub.