{"record":{"id":"43062e41243c52e0","repo":"GoogleContainerTools/skaffold","slug":"unknown-panic","errorCode":null,"errorMessage":"unknown panic","messagePattern":"unknown panic","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/skaffold/schema/util/upgrade_pipelines.go","lineNumber":40,"sourceCode":"\t\"reflect\"\n)\n\ntype pipelineUpgrader struct {\n\toldConfig reflect.Value\n\tnewConfig reflect.Value\n\tupgrade   func(o, n interface{}) error\n}\n\nfunc UpgradePipelines(oldConfig, newConfig interface{}, upgrade func(o, n interface{}) error) (err error) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tswitch x := r.(type) {\n\t\t\tcase string:\n\t\t\t\terr = fmt.Errorf(\"upgrading pipelines failed: %s\", x)\n\t\t\tcase error:\n\t\t\t\terr = x\n\t\t\tdefault:\n\t\t\t\terr = errors.New(\"unknown panic\")\n\t\t\t}\n\t\t}\n\t}()\n\n\tupgrader := pipelineUpgrader{\n\t\toldConfig: reflect.Indirect(reflect.ValueOf(oldConfig)),\n\t\tnewConfig: reflect.Indirect(reflect.ValueOf(newConfig)),\n\t\tupgrade:   upgrade,\n\t}\n\n\tif err := upgrader.mainPipeline(); err != nil {\n\t\treturn err\n\t}\n\n\treturn upgrader.profiles()\n}\n\nfunc (u *pipelineUpgrader) mainPipeline() error {","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/schema/util/upgrade_pipelines.go#L22-L58","documentation":"UpgradeToLatestUTF8Pipelines recovers from panics raised inside per-pipeline upgraders so one bad pipeline doesn't crash the process. If the recovered value r is neither a string nor an error (e.g. a panic value like an int or a custom struct), the code cannot classify it and throws this generic error.","triggerScenarios":"A pipelineUpgrader (or code it calls) panics with a non-string, non-error value while upgrading an old schema config's pipelines to latest.","commonSituations":"Schema upgrade code panicking via index-out-of-range or a panic(err/nil) with an unusual payload during `skaffold fix` on an old skaffold.yaml.","solutions":["Inspect which pipeline upgrader panics and fix it to panic with an error or string.","Update skaffold to a version where the offending upgrade panic is fixed.","Work around by manually editing skaffold.yaml to a schema version that upgrades cleanly, then rerun the upgrade."],"exampleFix":"// before\npanic(42) // recovered as \"unknown panic\"\n// after\npanic(fmt.Errorf(\"cannot upgrade pipeline %d: %v\", i, reason))","handlingStrategy":"try-catch","validationCode":"// Ensure upgrader implementations only panic with error/string values; audit custom upgraders before use.","typeGuard":"switch v := r.(type) { case error: ...; case string: ...; default: /* unknown panic */ }","tryCatchPattern":"cfg, err := util.UpgradeToLatestUTF8Pipelines(old)\nif err != nil {\n    if err.Error() == \"unknown panic\" {\n        log.Printf(\"upgrader panicked with non-error value; report bug\")\n    }\n    return err\n}","preventionTips":["Only register upgraders that panic with error values","Keep skaffold updated to pick up upgrader fixes","Run upgrades on a copy of the config"],"tags":["panic","recovery","schema-upgrade"],"backgroundTag":"unclassified-panic","analyzedSha":"a1189de023efc32d4b8e11f395acc678aa555011","analyzedAt":"2026-09-05T12:09:27.064Z","contentChangedAt":"2026-09-05T12:09:27.064Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}