{"record":{"id":"0499dc46775e3d97","repo":"vitessio/vitess","slug":"panic-err-error-from-partitions-executetohtml-s","errorCode":null,"errorMessage":"panic(err) — error from partitions.ExecuteToHTML(st.Value)","messagePattern":"panic\\(err\\) — error from partitions\\.ExecuteToHTML\\(st\\.Value\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/srvtopo/status.go","lineNumber":148,"sourceCode":"{{ range .Partitions }}\n&nbsp;<b>{{ .ServedType }}:</b>\n{{ range .ShardReferences }}\n&nbsp;{{ .Name }}\n{{ end }}\n<br>\n{{ end }}\n`))\n)\n\n// StatusAsHTML returns an HTML version of our status.\n// It works best if there is data in the cache.\nfunc (st *SrvKeyspaceCacheStatus) StatusAsHTML() safehtml.HTML {\n\tif st.Value == nil {\n\t\treturn noData\n\t}\n\thtml, err := partitions.ExecuteToHTML(st.Value)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn html\n}\n\n// SrvKeyspaceCacheStatusList is used for sorting\ntype SrvKeyspaceCacheStatusList []*SrvKeyspaceCacheStatus\n\n// Len is part of sort.Interface\nfunc (skcsl SrvKeyspaceCacheStatusList) Len() int {\n\treturn len(skcsl)\n}\n\n// Less is part of sort.Interface\nfunc (skcsl SrvKeyspaceCacheStatusList) Less(i, j int) bool {\n\treturn skcsl[i].Cell+\".\"+skcsl[i].Keyspace <\n\t\tskcsl[j].Cell+\".\"+skcsl[j].Keyspace\n}\n","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/srvtopo/status.go#L130-L166","documentation":"SrvKeyspaceCacheStatus.StatusAsHTML renders the cached srvkeyspace partitions via a Go template (partitions.ExecuteToHTML). If template execution fails, it panics with the template error instead of returning it, because the debug/status HTML endpoint has no error return path. A panic here means the cached value does not match the template's expectations.","triggerScenarios":"Calling StatusAsHTML when st.Value holds a SrvKeyspacesPartitions object whose data violates the template contract (nil/missing fields the template dereferences, wrong dynamic type), causing ExecuteToHTML to return an error.","commonSituations":"Visiting the /srvkeyspace debug status page on a vttablet/vtgate whose srvkeyspace cache was populated by an older or newer Vitess version with a changed partition structure; partially initialized cache status served before the first update completed; hand-constructed values in tests.","solutions":["Restart the vtgate/vttablet process so the srvkeyspace cache is repopulated by the current code version.","Confirm all components are on the same Vitess version so the cached SrvKeyspacesPartitions shape matches the template.","If reproducible, file a bug with the template error: the panic wraps the underlying ExecuteToHTML error which names the failing field."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"// StatusAsHTML has no error return; wrap the caller with a recover for the debug endpoint.\nfunc safeStatusAsHTML(st *srvtopo.SrvKeyspaceCacheStatus) (out safehtml.HTML) {\n  defer func() {\n    if r := recover(); r != nil {\n      out = safehtml.HTML(fmt.Sprintf(\"<pre>status render failed: %v</pre>\", r))\n    }\n  }()\n  return st.StatusAsHTML()\n}","preventionTips":["Keep all Vitess components on the same version so cached status shapes match the templates","Restart vtgate/vttablet if the debug status page panics after an upgrade","Reproduce template failures with the wrapped error before filing a bug"],"tags":["go","panic","template-rendering","debug-status"],"backgroundTag":"template-execution-failed","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}