{"record":{"id":"0ed5888bf6f30a5b","repo":"temporalio/temporal","slug":"version-history-cannot-be-null","errorCode":null,"errorMessage":"version history cannot be null","messagePattern":"version history cannot be null","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/persistence/versionhistory/version_histories.go","lineNumber":11,"sourceCode":"package versionhistory\n\nimport (\n\t\"go.temporal.io/api/serviceerror\"\n\thistoryspb \"go.temporal.io/server/api/history/v1\"\n)\n\n// NewVersionHistories create a new instance of VersionHistories.\nfunc NewVersionHistories(versionHistory *historyspb.VersionHistory) *historyspb.VersionHistories {\n\tif versionHistory == nil {\n\t\tpanic(\"version history cannot be null\")\n\t}\n\n\treturn &historyspb.VersionHistories{\n\t\tCurrentVersionHistoryIndex: 0,\n\t\tHistories:                  []*historyspb.VersionHistory{versionHistory},\n\t}\n}\n\n// Copy VersionHistories.\nfunc CopyVersionHistories(h *historyspb.VersionHistories) *historyspb.VersionHistories {\n\tvar histories []*historyspb.VersionHistory\n\tfor _, history := range h.Histories {\n\t\thistories = append(histories, CopyVersionHistory(history))\n\t}\n\n\treturn &historyspb.VersionHistories{\n\t\tCurrentVersionHistoryIndex: h.CurrentVersionHistoryIndex,\n\t\tHistories:                  histories,","sourceCodeStart":1,"sourceCodeEnd":29,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/common/persistence/versionhistory/version_histories.go#L1-L29","documentation":"NewVersionHistories wraps an initial VersionHistory into the VersionHistories container used by execution state; it panics immediately if the input VersionHistory is nil. A VersionHistories with no first branch is structurally meaningless (CurrentVersionHistoryIndex would point at nothing), so the constructor enforces the non-nil invariant at creation time.","triggerScenarios":"Calling versionhistory.NewVersionHistories(nil), typically when the caller obtained the VersionHistory from a proto field (e.g. mutableState.VersionHistories or a branch token lookup) that was unset, or when building execution info from partially decoded state.","commonSituations":"Replaying history where the versioning info proto is missing/old (version skew between clusters); test helpers passing a nil branch; constructing WorkflowExecutionInfo from a mutable state blob that predates versioning.","solutions":["Pass a freshly constructed branch, e.g. NewVersionHistories(NewVersionHistory(NewVersionHistoryItem(firstEventID, firstVersion))), when bootstrapping a new execution.","Guard the input: if the source VersionHistory is nil, create a default initial version history instead of passing nil through.","Check that the proto field you sourced the history from (branch token / mutable state) is actually populated before calling.","Upgrade/sync cluster versions if nil histories come from older persisted state."],"exampleFix":"// before\nhistories := versionhistory.NewVersionHistories(mutableState.GetVersionHistories().GetHistories()[idx]) // may be nil\n// after\nvh := mutableState.GetVersionHistories().GetHistories()[idx]\nif vh == nil {\n    vh = versionhistory.NewVersionHistory(versionhistory.NewVersionHistoryItem(1, 1))\n}\nhistories := versionhistory.NewVersionHistories(vh)","handlingStrategy":"validation","validationCode":"func safeNewVersionHistories(vh *historyspb.VersionHistory) (*historyspb.VersionHistories, error) {\n    if vh == nil || len(vh.GetItems()) == 0 {\n        return nil, errors.New(\"input version history is nil or empty\")\n    }\n    return versionhistory.NewVersionHistories(vh), nil\n}","typeGuard":"func versionHistoryExists(vh *historyspb.VersionHistory) bool { return vh != nil && len(vh.GetItems()) > 0 }","tryCatchPattern":"// Go panics cannot be caught as errors; guard the input instead of recovering\nif vh == nil { return nil, internalErr }\nhistories := versionhistory.NewVersionHistories(vh)","preventionTips":["Bootstrap executions only via NewVersionHistory(NewVersionHistoryItem(...)) defaults","Validate mutable state protos after deserialization (version skew checks)","Never pass proto sub-message fields straight into constructors without nil checks"],"tags":["persistence","panic","version-history","nil"],"backgroundTag":"nil-version-history","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}