dagger/dagger · error

clone detached file for container result: file must be mater

Error message

clone detached file for container result: file must be materialized, got lazy %T

What it means

Symmetric with the directory case: cloneDetachedFileForContainerResult clones a *File for a container result and rejects files whose Lazy accessor is still set, since detached clone needs fully materialized file contents. The offending lazy type is reported via %T.

Source

Thrown at core/container.go:917

	query, err := CurrentQuery(ctx)
	if err != nil {
		return nil, err
	}
	reopened, err := query.SnapshotManager().GetBySnapshotID(ctx, snapshot.SnapshotID(), bkcache.NoUpdateLastUsed)
	if err != nil {
		return nil, err
	}
	cp.Snapshot.setValue(reopened)
	return cp, nil
}

//nolint:dupl // symmetric with cloneDetachedDirectoryForContainerResult; sharing obscures type specifics
func cloneDetachedFileForContainerResult(ctx context.Context, src *File) (*File, error) {
	if src == nil {
		return nil, nil
	}
	if src.Lazy != nil {
		return nil, fmt.Errorf("clone detached file for container result: file must be materialized, got lazy %T", src.Lazy)
	}

	cp := &File{
		Platform: src.Platform,
		Services: slices.Clone(src.Services),
		File:     new(LazyAccessor[string, *File]),
		Snapshot: new(LazyAccessor[bkcache.ImmutableRef, *File]),
	}
	if filePath, ok := src.File.Peek(); ok {
		cp.File.setValue(filePath)
	}

	snapshot, ok := src.Snapshot.Peek()
	if !ok || snapshot == nil {
		return cp, nil
	}

	query, err := CurrentQuery(ctx)

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Evaluate/materialize the File before cloning so src.Lazy is cleared
  2. Change the caller to handle lazy files by going through the standard (non-detached) copy path that performs evaluation
  3. In custom code, construct File the same way the engine does — new(LazyAccessor[string, *File]) plus loaded content, no leftover Lazy

Example fix

// before
if f.Lazy != nil {
    cp, err := cloneDetachedFileForContainerResult(ctx, f) // errors: got lazy
}
// after
f, err := f.Evaluate(ctx) // materialize file contents first
if err != nil { return err }
cp, err := cloneDetachedFileForContainerResult(ctx, f)
Defensive patterns

Strategy: validation

Validate before calling

if file.Lazy != nil {
    // materialize first: file, err = file.Evaluate(ctx)
}
cp, err := cloneDetachedFileForContainerResult(ctx, file)

Type guard

func isMaterializedFile(f *core.File) bool { return f == nil || f.Lazy == nil }

Prevention

When it happens

Trigger: A detach/export flow hands a lazily-backed *File (unevaluated accessor) to cloneDetachedFileForContainerResult — e.g. a File obtained from a container without first evaluating its contents.

Common situations: Exporting a lazily derived file (from container.File/copy) before its contents were resolved; engine bugs skipping file materialization; forks constructing File with Lazy non-nil.

Related errors


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