{"record":{"id":"9e479f32766d9cc1","repo":"dagger/dagger","slug":"failed-to-write-diff","errorCode":null,"errorMessage":"failed to write diff","messagePattern":"failed to write diff","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/snapshots/blobs_linux.go","lineNumber":89,"sourceCode":"\t\tdgstr := digest.SHA256.Digester()\n\t\tcompressed, err := compressorFunc(bufW, mediaType)\n\t\tif err != nil {\n\t\t\treturn emptyDesc, false, errors.Wrap(err, \"failed to get compressed stream\")\n\t\t}\n\t\t// Close ensure compressorFunc does some finalization works.\n\t\tdefer compressed.Close()\n\t\tif err := overlay.WriteUpperdir(ctx, io.MultiWriter(compressed, dgstr.Hash()), upperdir, lower); err != nil {\n\t\t\treturn emptyDesc, false, errors.Wrap(err, \"failed to write compressed diff\")\n\t\t}\n\t\tif err := compressed.Close(); err != nil {\n\t\t\treturn emptyDesc, false, errors.Wrap(err, \"failed to close compressed diff writer\")\n\t\t}\n\t\tlabels = map[string]string{\n\t\t\tlabelspkg.LabelUncompressed: dgstr.Digest().String(),\n\t\t}\n\t} else {\n\t\tif err = overlay.WriteUpperdir(ctx, bufW, upperdir, lower); err != nil {\n\t\t\treturn emptyDesc, false, errors.Wrap(err, \"failed to write diff\")\n\t\t}\n\t}\n\n\tif err := bufW.Flush(); err != nil {\n\t\treturn emptyDesc, false, errors.Wrap(err, \"failed to flush diff\")\n\t}\n\tvar commitopts []content.Opt\n\tif labels != nil {\n\t\tcommitopts = append(commitopts, content.WithLabels(labels))\n\t}\n\tdgst := cw.Digest()\n\tif err := cw.Commit(ctx, 0, dgst, commitopts...); err != nil {\n\t\tif !cerrdefs.IsAlreadyExists(err) {\n\t\t\treturn emptyDesc, false, errors.Wrap(err, \"failed to commit\")\n\t\t}\n\t}\n\tif err := cw.Close(); err != nil {\n\t\treturn emptyDesc, false, err","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/dagger/dagger/blob/82ba2681dbe30d3547a1dc50ea495900ab5b6047/engine/snapshots/blobs_linux.go#L71-L107","documentation":"In the non-compressed path of tryComputeOverlayBlob, the overlay upperdir diff is written directly into the buffered content writer via overlay.WriteUpperdir. Failure here (walking the diff or writing bytes) aborts with 'failed to write diff'. It is the uncompressed counterpart of 'failed to write compressed diff'.","triggerScenarios":"overlay.WriteUpperdir(ctx, bufW, upperdir, lower) returning an error when no compressorFunc is configured — e.g. files vanishing during the walk, unreadable entries, write errors to the content-store writer, or context cancellation.","commonSituations":"Snapshot mutation/GC during diff; disk full on the content store; permission or xattr read failures on upperdir files; kernel/overlayfs quirks with whiteouts.","solutions":["Read the wrapped inner error for the precise cause.","Ensure the snapshot isn't being pruned concurrently while exporting (serialize export vs prune).","Check content-store disk space and volume health.","Re-run the build; clear corrupt snapshot state if errors persist."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"_, ok, err := ref.tryComputeOverlayBlob(ctx, lower, upper, mediaType, refID, nil)\nif err != nil && strings.Contains(err.Error(), \"failed to write diff\") {\n\tlog.Printf(\"uncompressed diff write failed: %v\", errors.Cause(err))\n\t// fall back to a fresh diff pass or walking differ after disk check\n}","preventionTips":["Serialize export against prune so snapshot files aren't removed mid-walk","Ensure read access and stable xattrs on upperdir files","Keep free disk space for the uncompressed blob (largest case)","Retry transient failures — snapshot mutation races are often one-off"],"tags":["overlayfs","io","filesystem-diff","buildkit"],"backgroundTag":"overlay-diff-write-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"}