{"record":{"id":"a04cbc57791e5c94","repo":"dagger/dagger","slug":"failed-to-check-for-changes-w","errorCode":null,"errorMessage":"failed to check for changes: %w","messagePattern":"failed to check for changes: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/service.go","lineNumber":1505,"sourceCode":"\t}()\n\n\terr = MountRef(ctx, mutableRef, func(root string, _ *mount.Mount) (rerr error) {\n\t\tresolvedDir, err := containerdfs.RootPath(root, sourceDirPath)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := mountIntoContainer(ctx, running.ContainerID, resolvedDir, target); err != nil {\n\t\t\treturn fmt.Errorf(\"remount container: %w\", err)\n\t\t}\n\t\treturn f()\n\t})\n\tif err != nil {\n\t\treturn res, false, err\n\t}\n\n\tusage, err := bk.Snapshotter.Usage(ctx, mutableRef.SnapshotID())\n\tif err != nil {\n\t\treturn res, false, fmt.Errorf(\"failed to check for changes: %w\", err)\n\t}\n\thasChanges = usage.Inodes > 1 || usage.Size > 0\n\tif !hasChanges {\n\t\tslog.Debug(\"mcp: no changes made to directory\")\n\t\treturn res, false, nil\n\t}\n\n\timmutableRef, err := mutableRef.Commit(ctx)\n\tif err != nil {\n\t\treturn res, false, fmt.Errorf(\"failed to commit remounted ref for %s: %w\", target, err)\n\t}\n\tmutableRef = nil\n\n\t// Create a new mutable ref to leave the service with, to prevent further\n\t// changes from mutating the now-immutable ref\n\t//\n\t// NOTE: there's technically a race here, for sure, but we can least prevent\n\t// mutation outside of the bounds of this func","sourceCodeStart":1487,"sourceCodeEnd":1523,"githubUrl":"https://github.com/dagger/dagger/blob/82ba2681dbe30d3547a1dc50ea495900ab5b6047/core/service.go#L1487-L1523","documentation":"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\".","triggerScenarios":"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.","commonSituations":"Long-running functions inside the snapshot callback that outlive context deadlines; concurrent GC removing the record; engine cache backend issues.","solutions":["Inspect the wrapped cause: if context deadline exceeded, increase the timeout or avoid long work inside the callback","Check no concurrent cache GC/prune runs during the operation","Retry the operation; the snapshot should still exist within the same call","Verify disk health and snapshotter backend (overlayfs) support on the host"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"select {\ncase <-ctx.Done():\n    return fmt.Errorf(\"context done before snapshot usage check: %w\", ctx.Err())\ndefault:\n}","typeGuard":null,"tryCatchPattern":"err := runSnapshotOp(ctx)\nif err != nil && strings.Contains(err.Error(), \"failed to check for changes\") {\n    if errors.Is(err, context.DeadlineExceeded) {\n        return retryWithLongerTimeout(ctx, runSnapshotOp)\n    }\n    return err\n}","preventionTips":["Use generous timeouts when functions write into mounted service directories","Avoid cancelling the parent context mid-operation","Prevent concurrent GC during snapshot operations"],"tags":["snapshotter","buildkit","usage","context"],"backgroundTag":"snapshotter-usage-failed","analyzedSha":"82ba2681dbe30d3547a1dc50ea495900ab5b6047","analyzedAt":"2026-09-05T07:21:37.930Z","contentChangedAt":"2026-09-05T07:21:37.930Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}