dagger/dagger · error

failed to check for changes: %w

Error message

failed to check for changes: %w

What it means

To decide whether the mounted-in function changed anything, the code queries the buildkit snapshotter's Usage for the mutable ref's snapshot ID. If that snapshotter lookup fails (snapshot removed, snapshotter unavailable, context cancelled), the error is wrapped as "failed to check for changes".

Source

Thrown at core/service.go:1505

	}()

	err = MountRef(ctx, mutableRef, func(root string, _ *mount.Mount) (rerr error) {
		resolvedDir, err := containerdfs.RootPath(root, sourceDirPath)
		if err != nil {
			return err
		}
		if err := mountIntoContainer(ctx, running.ContainerID, resolvedDir, target); err != nil {
			return fmt.Errorf("remount container: %w", err)
		}
		return f()
	})
	if err != nil {
		return res, false, err
	}

	usage, err := bk.Snapshotter.Usage(ctx, mutableRef.SnapshotID())
	if err != nil {
		return res, false, fmt.Errorf("failed to check for changes: %w", err)
	}
	hasChanges = usage.Inodes > 1 || usage.Size > 0
	if !hasChanges {
		slog.Debug("mcp: no changes made to directory")
		return res, false, nil
	}

	immutableRef, err := mutableRef.Commit(ctx)
	if err != nil {
		return res, false, fmt.Errorf("failed to commit remounted ref for %s: %w", target, err)
	}
	mutableRef = nil

	// Create a new mutable ref to leave the service with, to prevent further
	// changes from mutating the now-immutable ref
	//
	// NOTE: there's technically a race here, for sure, but we can least prevent
	// mutation outside of the bounds of this func

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Inspect the wrapped cause: if context deadline exceeded, increase the timeout or avoid long work inside the callback
  2. Check no concurrent cache GC/prune runs during the operation
  3. Retry the operation; the snapshot should still exist within the same call
  4. Verify disk health and snapshotter backend (overlayfs) support on the host
Defensive patterns

Strategy: try-catch

Validate before calling

select {
case <-ctx.Done():
    return fmt.Errorf("context done before snapshot usage check: %w", ctx.Err())
default:
}

Try / catch

err := runSnapshotOp(ctx)
if err != nil && strings.Contains(err.Error(), "failed to check for changes") {
    if errors.Is(err, context.DeadlineExceeded) {
        return retryWithLongerTimeout(ctx, runSnapshotOp)
    }
    return err
}

Prevention

When it happens

Trigger: bk.Snapshotter.Usage(ctx, mutableRef.SnapshotID()) errors — e.g. the snapshot was concurrently released/pruned, the context expired mid-call, or the snapshotter backend (overlayfs/native) failed to stat usage.

Common situations: Long-running functions inside the snapshot callback that outlive context deadlines; concurrent GC removing the record; engine cache backend issues.

Related errors


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