GoogleContainerTools/skaffold · error

lengths of old and new profiles differ

Error message

lengths of old and new profiles differ

What it means

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.

Source

Thrown at pkg/skaffold/schema/util/upgrade_pipelines.go:82

	err := u.upgrade(oldPipeline, newPipeline)
	if err != nil {
		return fmt.Errorf("upgrading main pipeline: %w", err)
	}

	return nil
}

func (u *pipelineUpgrader) profiles() error {
	const (
		fieldProfilePipeline = "Pipeline"
		fieldProfiles        = "Profiles"
	)

	profilesOld := u.oldConfig.FieldByName(fieldProfiles)
	profilesNew := u.newConfig.FieldByName(fieldProfiles)

	if profilesOld.Len() != profilesNew.Len() {
		return fmt.Errorf("lengths of old and new profiles differ")
	}

	for i := 0; i < profilesOld.Len(); i++ {
		oldPipeline := profilesOld.Index(i).FieldByName(fieldProfilePipeline).Addr().Interface()
		newPipeline := profilesNew.Index(i).FieldByName(fieldProfilePipeline).Addr().Interface()

		if err := u.upgrade(oldPipeline, newPipeline); err != nil {
			return fmt.Errorf("upgrading pipeline of profile %d: %w", i+1, err)
		}
	}

	return nil
}

View on GitHub (pinned to a1189de023)

Solutions

  1. Check the versioned Upgrade() for code that mutates the Profiles slice; ensure it only upgrades in place
  2. Diff old vs new config profiles to find the added/removed profile entry
  3. Ensure profiles survive CloneThroughJSON — verify field names/types between versions match for the profiles list
Defensive patterns

Strategy: validation

Validate before calling

if len(old.Profiles) != len(new.Profiles) { return errors.New("profiles count changed during upgrade") }

Try / catch

if err := util.UpgradePipelines(old, new, upgradeFn); err != nil {
	if strings.Contains(err.Error(), "lengths of old and new profiles differ") {
		// diff profiles before/after
	}
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05). Data as JSON: /api/errors/fcc2a4092886f12d. Report an issue: GitHub.