{"record":{"id":"90efeb82620b71b9","repo":"temporalio/temporal","slug":"unknown-persistence-task-predicate-type-v","errorCode":null,"errorMessage":"unknown persistence task predicate type: %v","messagePattern":"unknown persistence task predicate type: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"service/history/queues/convert.go","lineNumber":157,"sourceCode":"\t\treturn FromPersistenceEmptyPredicate(predicate.GetEmptyPredicateAttributes())\n\tcase enumsspb.PREDICATE_TYPE_AND:\n\t\treturn FromPersistenceAndPredicate(predicate.GetAndPredicateAttributes())\n\tcase enumsspb.PREDICATE_TYPE_OR:\n\t\treturn FromPersistenceOrPredicate(predicate.GetOrPredicateAttributes())\n\tcase enumsspb.PREDICATE_TYPE_NOT:\n\t\treturn FromPersistenceNotPredicate(predicate.GetNotPredicateAttributes())\n\tcase enumsspb.PREDICATE_TYPE_NAMESPACE_ID:\n\t\treturn FromPersistenceNamespaceIDPredicate(predicate.GetNamespaceIdPredicateAttributes())\n\tcase enumsspb.PREDICATE_TYPE_TASK_TYPE:\n\t\treturn FromPersistenceTaskTypePredicate(predicate.GetTaskTypePredicateAttributes())\n\tcase enumsspb.PREDICATE_TYPE_DESTINATION:\n\t\treturn FromPersistenceDestinationPredicate(predicate.GetDestinationPredicateAttributes())\n\tcase enumsspb.PREDICATE_TYPE_OUTBOUND_TASK_GROUP:\n\t\treturn FromPersistenceOutboundTaskGroupPredicate(predicate.GetOutboundTaskGroupPredicateAttributes())\n\tcase enumsspb.PREDICATE_TYPE_OUTBOUND_TASK:\n\t\treturn FromPersistenceOutboundTaskPredicate(predicate.GetOutboundTaskPredicateAttributes())\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"unknown persistence task predicate type: %v\", predicate.GetPredicateType()))\n\t}\n}\n\nfunc ToPersistenceUniversalPredicate(\n\t_ *predicates.UniversalImpl[tasks.Task],\n) *persistencespb.Predicate {\n\treturn &persistencespb.Predicate{\n\t\tPredicateType: enumsspb.PREDICATE_TYPE_UNIVERSAL,\n\t\tAttributes:    &persistencespb.Predicate_UniversalPredicateAttributes{},\n\t}\n}\n\nfunc FromPersistenceUniversalPredicate(\n\t_ *persistencespb.UniversalPredicateAttributes,\n) tasks.Predicate {\n\treturn predicates.Universal[tasks.Task]()\n}\n","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/service/history/queues/convert.go#L139-L175","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\ndefault:\n    panic(fmt.Sprintf(\"unknown persistence task predicate type: %v\", predicate.GetPredicateType()))\n// after\ncase enumsspb.PREDICATE_TYPE_MY_NEW:\n    return FromPersistenceMyNewPredicate(predicate.GetMyNewPredicateAttributes())\ndefault:\n    return predicates.EmptyTaskPredicate(), nil // or log + fall back","handlingStrategy":"validation","validationCode":"if p.GetPredicateType() == enumsspb.PREDICATE_TYPE_UNSPECIFIED ||\n    !knownPredicateTypes[p.GetPredicateType()] {\n    // fall back to empty/ALL predicate instead of deserializing\n    return predicates.EmptyTaskPredicate()\n}","typeGuard":null,"tryCatchPattern":"func safeFromPersistence(p *persistencespb.Predicate) (out tasks.Predicate) {\n    defer func() {\n        if r := recover(); r != nil {\n            out = predicates.EmptyTaskPredicate()\n        }\n    }()\n    out = queues.FromPersistencePredicate(p)\n    return\n}","preventionTips":["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"],"tags":["go","panic","deserialization","proto-compat","history-service"],"backgroundTag":"unknown-enum-deserialization","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}