{"record":{"id":"25a9f00034abea61","repo":"dagger/dagger","slug":"w-w","errorCode":null,"errorMessage":"%w; %w","messagePattern":"%w; %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"core/client_filesync_mirror.go","lineNumber":298,"sourceCode":"\tif m.mounter != nil {\n\t\trerr = errorsJoin(rerr, m.mounter.Unmount())\n\t\tm.mounter = nil\n\t}\n\tm.mntPath = \"\"\n\tm.sharedState = nil\n\treturn rerr\n}\n\nfunc errorsJoin(errs ...error) error {\n\tvar out error\n\tfor _, err := range errs {\n\t\tif err == nil {\n\t\t\tcontinue\n\t\t}\n\t\tif out == nil {\n\t\t\tout = err\n\t\t} else {\n\t\t\tout = fmt.Errorf(\"%w; %w\", out, err)\n\t\t}\n\t}\n\treturn out\n}\n\nfunc NewEphemeralClientFilesyncMirror(drive string) *ClientFilesyncMirror {\n\treturn &ClientFilesyncMirror{\n\t\tDrive:       drive,\n\t\tEphemeralID: identity.NewID(),\n\t}\n}\n","sourceCodeStart":280,"sourceCodeEnd":310,"githubUrl":"https://github.com/dagger/dagger/blob/82ba2681dbe30d3547a1dc50ea495900ab5b6047/core/client_filesync_mirror.go#L280-L310","documentation":"errorsJoin aggregates multiple errors from mirror release/teardown paths into a single error using fmt.Errorf(\"%w; %w\"), joining the accumulated error with each subsequent one. It is an internal convenience so no release-time error is silently dropped; the joined error supports errors.Is/As against every constituent via the two %w verbs.","triggerScenarios":"OnRelease or releaseRuntimeLocked returns more than one non-nil error (e.g. snapshot close fails and runtime resource release also fails), and errorsJoin combines them with \"; \" separators.","commonSituations":"Teardown of a client filesync mirror at session end where both snapshot release and runtime cleanup fail; shutdown races producing multiple independent release errors.","solutions":["Inspect both halves of the joined message — each %w branch is a distinct release error","Use errors.Is/errors.As on the returned error to match specific constituent errors","Fix the underlying release failures; the join itself is informational","Check for resource-leak warnings if only one side consistently fails"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func splitJoinedErr(err error) []error {\n    var errs []error\n    if e := errors.Unwrap(err); e != nil { errs = append(errs, e) }\n    return errs // use errors.Is/As across the whole chain instead\n}","tryCatchPattern":"if err := mirror.OnRelease(ctx); err != nil {\n    // both branches are wrapped with %w, so:\n    if errors.Is(err, targetErr1) || errors.Is(err, targetErr2) { ... }\n    log.Printf(\"release errors: %v\", err)\n}","preventionTips":["Ensure snapshot close and runtime release paths are idempotent","Log both halves of joined messages — each \"; \"-separated part is a distinct error","Treat release-time errors as warnings unless they cause resource leaks"],"tags":["error-joining","cleanup","filesync"],"backgroundTag":"multiple-errors-joined","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"}