{"record":{"id":"fcc2a4092886f12d","repo":"GoogleContainerTools/skaffold","slug":"lengths-of-old-and-new-profiles-differ","errorCode":null,"errorMessage":"lengths of old and new profiles differ","messagePattern":"lengths of old and new profiles differ","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/skaffold/schema/util/upgrade_pipelines.go","lineNumber":82,"sourceCode":"\terr := u.upgrade(oldPipeline, newPipeline)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"upgrading main pipeline: %w\", err)\n\t}\n\n\treturn nil\n}\n\nfunc (u *pipelineUpgrader) profiles() error {\n\tconst (\n\t\tfieldProfilePipeline = \"Pipeline\"\n\t\tfieldProfiles        = \"Profiles\"\n\t)\n\n\tprofilesOld := u.oldConfig.FieldByName(fieldProfiles)\n\tprofilesNew := u.newConfig.FieldByName(fieldProfiles)\n\n\tif profilesOld.Len() != profilesNew.Len() {\n\t\treturn fmt.Errorf(\"lengths of old and new profiles differ\")\n\t}\n\n\tfor i := 0; i < profilesOld.Len(); i++ {\n\t\toldPipeline := profilesOld.Index(i).FieldByName(fieldProfilePipeline).Addr().Interface()\n\t\tnewPipeline := profilesNew.Index(i).FieldByName(fieldProfilePipeline).Addr().Interface()\n\n\t\tif err := u.upgrade(oldPipeline, newPipeline); err != nil {\n\t\t\treturn fmt.Errorf(\"upgrading pipeline of profile %d: %w\", i+1, err)\n\t\t}\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":64,"sourceCodeEnd":96,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/schema/util/upgrade_pipelines.go#L64-L96","documentation":"pipelineUpgrader.profiles upgrades each entry of the 'profiles' list. Because the caller (UpgradePipelines) clones the old config into the new versioned struct via CloneThroughJSON, both lists must have identical length. This error means the new config's profiles list differs in size from the old one, breaking the pairwise index-based upgrade and indicating the versioned Upgrade() added or dropped profile entries incorrectly.","triggerScenarios":"A custom or versioned Upgrade() function that appends, filters, or drops entries in c.Profiles before pipelineUpgrader.profiles() runs, so len(old.Profiles) != len(new.Profiles).","commonSituations":"Hand-written upgrade functions between schema versions that rename/merge profile fields using JSON round-trips that drop unknown profile entries; deeply customized configs with unusual profile blocks.","solutions":["Check the versioned Upgrade() for code that mutates the Profiles slice; ensure it only upgrades in place","Diff old vs new config profiles to find the added/removed profile entry","Ensure profiles survive CloneThroughJSON — verify field names/types between versions match for the profiles list"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if len(old.Profiles) != len(new.Profiles) { return errors.New(\"profiles count changed during upgrade\") }","typeGuard":null,"tryCatchPattern":"if err := util.UpgradePipelines(old, new, upgradeFn); err != nil {\n\tif strings.Contains(err.Error(), \"lengths of old and new profiles differ\") {\n\t\t// diff profiles before/after\n\t}\n}","preventionTips":["Never mutate the Profiles slice length inside a custom upgrade function","Ensure field names/types for profiles match between schema versions so JSON cloning preserves entries","Test upgrade functions against configs with multiple profiles"],"tags":["go","reflection","schema-upgrade"],"backgroundTag":"schema-upgrade-length-mismatch","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"}