dagger/dagger · error

materialize changes for changeset %d: %w

Error message

materialize changes for changeset %d: %w

What it means

During multiway merging, each incoming changeset's content is materialized in a parallel job named 'changeset %d changes'; failures are wrapped with the changeset index. This identifies exactly which of the N incoming changesets could not have its content materialized.

Source

Thrown at core/changeset.go:1208

	}

	// Each diff is an independent snapshot-diff materialization, so take them
	// all at once.
	var ourContent *changesetContent
	otherContents := make([]*changesetContent, len(others))
	contentJobs := changesetJobs().WithJob("self changes", func(ctx context.Context) error {
		content, err := ch.content(ctx)
		if err != nil {
			return fmt.Errorf("materialize our changes: %w", err)
		}
		ourContent = content
		return nil
	})
	for i, other := range others {
		contentJobs = contentJobs.WithJob(fmt.Sprintf("changeset %d changes", i), func(ctx context.Context) error {
			content, err := other.content(ctx)
			if err != nil {
				return fmt.Errorf("materialize changes for changeset %d: %w", i, err)
			}
			otherContents[i] = content
			return nil
		})
	}
	if err := contentJobs.Run(ctx); err != nil {
		return nil, err
	}

	afterDir, err := enginetel.TaskRet(ctx, "octopus merge", func(ctx context.Context) (*Directory, error) {
		return gitOctopusMergeChangesets(ctx, before, ourContent, otherContents)
	})
	if err != nil {
		return nil, err
	}

	return enginetel.TaskRet(ctx, "new changeset from merge", func(ctx context.Context) (*Changeset, error) {
		return newChangesetFromMerge(ctx, before, afterDir)

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Use the index in the message to locate the failing changeset and inspect its wrapped cause.
  2. Rebuild or drop the offending changeset and retry the merge.
  3. Materialize each changeset's content (via ComputePaths/Sync on After) before the batch merge to fail fast and localize errors.
  4. Retry with a fresh context; check engine logs for the failing dagql query.
Defensive patterns

Strategy: validation

Validate before calling

for i, cs := range others {
    if _, err := cs.ComputePaths(ctx); err != nil {
        return fmt.Errorf("changeset %d unusable before merge: %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 n, _ := fmt.Sscanf(err.Error(), "materialize changes for changeset %d", &idx); n == 1 {
        return fmt.Errorf("changeset at index %d could not be materialized: %w", idx, err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling the multiway merge API where other.content(ctx) fails for changeset i in the others slice - path computation, dagql Select, or EngineCache.Evaluate errors inside the parallel job.

Common situations: One of many merged changesets came from a failed or foreign pipeline; oversized directory content that fails evaluation; shared context cancelled by another job's failure.

Related errors


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