dagger/dagger · error

compute paths for changeset %d: %w

Error message

compute paths for changeset %d: %w

What it means

During multiway changeset merging, Dagger computes paths for each incoming changeset in parallel jobs and wraps any ComputePaths failure with the index of the offending changeset. The %d identifies which changeset in the 'others' slice failed, so you can pinpoint the bad input.

Source

Thrown at core/changeset.go:1149

func (ch *Changeset) WithChangesets(
	ctx context.Context,
	others []*Changeset,
	onConflictStrategy WithChangesetsMergeConflict,
) (*Changeset, error) {
	// Before wasting any effort, remove any changesets that are empty.
	//
	// This asks ComputePaths rather than IsEmpty: every surviving changeset
	// needs its paths computed anyway and ComputePaths memoizes, whereas
	// IsEmpty would mount and walk both trees all over again for each one. It
	// also counts directory-only changes, which IsEmpty deliberately ignores
	// the way `git diff --quiet` does.
	filtered := make([]*Changeset, len(others))
	jobs := changesetJobs()
	for i, other := range others {
		jobs = jobs.WithJob(fmt.Sprintf("changeset %d paths", i), func(ctx context.Context) error {
			paths, err := other.ComputePaths(ctx)
			if err != nil {
				return fmt.Errorf("compute paths for changeset %d: %w", i, err)
			}
			if !changesetPathsEmpty(paths) {
				filtered[i] = other
			}
			return nil
		})
	}
	if err := jobs.Run(ctx); err != nil {
		return nil, err
	}
	others = slices.DeleteFunc(filtered, func(cs *Changeset) bool { return cs == nil })

	if len(others) == 0 {
		return ch, nil
	}

	// Single element uses more efficient 2-way merge
	if len(others) == 1 {

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Use the %d index to find the failing changeset in your input slice and inspect its wrapped cause.
  2. Remove or rebuild the offending changeset from valid directories, then retry the merge.
  3. Pre-validate each changeset by calling ComputePaths individually before the batch merge.
  4. Retry with a fresh context if the failure was cancellation inside the parallel job.

Example fix

// before: merging an unvalidated batch
merged, err := base.WithChangesets(ctx, allOthers)
// after: validate each changeset's paths first
for i, cs := range allOthers {
    if _, err := cs.ComputePaths(ctx); err != nil {
        return fmt.Errorf("changeset %d invalid: %w", i, err)
    }
}
merged, err := base.WithChangesets(ctx, allOthers)
Defensive patterns

Strategy: validation

Validate before calling

for i, cs := range others {
    if cs == nil { return fmt.Errorf("changeset %d is nil", i) }
    if _, err := cs.ComputePaths(ctx); err != nil {
        return fmt.Errorf("changeset %d paths failed: %w", i, err)
    }
}

Type guard

func allChangesetsValid(others []*dagger.Changeset) bool {
    for _, cs := range others { if cs == nil { return false } }
    return true
}

Try / catch

merged, err := base.WithChangesets(ctx, others)
if err != nil {
    var idx int
    if _, err := fmt.Sscanf(err.Error(), "compute paths for changeset %d", &idx); err == nil {
        return fmt.Errorf("bad input changeset at index %d: %w", idx, err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling the multiway merge (WithChangesets / merge of N changesets) where changeset i's ComputePaths fails - its before/after directories cannot be diffed due to invalid IDs, evaluation errors, or cancellation inside the job.

Common situations: Passing a list of changesets where one was built from a failed step or another engine session; batch merges where a single stale changeset poisons the whole operation.

Related errors


AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05). Data as JSON: /api/errors/cfcbbe9ced77963b. Report an issue: GitHub.