{"record":{"id":"b4835649dc69a15d","repo":"docker/cli","slug":"builder-prune-has-been-cancelled","errorCode":null,"errorMessage":"builder prune has been cancelled","messagePattern":"builder prune has been cancelled","errorType":"exception","errorClass":"cancelledErr","httpStatus":null,"severity":"warning","filePath":"cli/command/builder/prune.go","lineNumber":84,"sourceCode":"const (\n\tnormalWarning   = `WARNING! This will remove all dangling build cache. Are you sure you want to continue?`\n\tallCacheWarning = `WARNING! This will remove all build cache. Are you sure you want to continue?`\n)\n\nfunc runPrune(ctx context.Context, dockerCli command.Cli, options pruneOptions) (spaceReclaimed uint64, output string, err error) {\n\tpruneFilters := command.PruneFilters(dockerCli, options.filter.Value())\n\n\twarning := normalWarning\n\tif options.all {\n\t\twarning = allCacheWarning\n\t}\n\tif !options.force {\n\t\tr, err := prompt.Confirm(ctx, dockerCli.In(), dockerCli.Out(), warning)\n\t\tif err != nil {\n\t\t\treturn 0, \"\", err\n\t\t}\n\t\tif !r {\n\t\t\treturn 0, \"\", cancelledErr{errors.New(\"builder prune has been cancelled\")}\n\t\t}\n\t}\n\n\tresp, err := dockerCli.Client().BuildCachePrune(ctx, client.BuildCachePruneOptions{\n\t\tAll:           options.all,\n\t\tReservedSpace: options.reservedSpace.Value(),\n\t\tFilters:       pruneFilters,\n\t})\n\tif err != nil {\n\t\treturn 0, \"\", err\n\t}\n\treport := resp.Report\n\tif len(report.CachesDeleted) > 0 {\n\t\tvar sb strings.Builder\n\t\tsb.WriteString(\"Deleted build cache objects:\\n\")\n\t\tfor _, id := range report.CachesDeleted {\n\t\t\tsb.WriteString(id)\n\t\t\tsb.WriteByte('\\n')","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cli/command/builder/prune.go#L66-L102","documentation":"In runPrune (cli/command/builder/prune.go:71) for 'docker builder prune', when --force/-f is not set, the CLI prompts for confirmation. If the user answers 'no', the function returns cancelledErr{errors.New(\"builder prune has been cancelled\")} at line 84. cancelledErr implements the containerd errdefs Cancelled() marker interface, so callers can detect it as an intentional cancellation rather than a hard failure.","triggerScenarios":"Running `docker builder prune` (without -f) and typing 'n'/no at the 'WARNING! ... Are you sure you want to continue?' prompt; or piping 'n' into the prompt's stdin.","commonSituations":"Automated/interactive scripts that forget -f and get the prompt; CI that answers 'no'; users aborting after reading the warning.","solutions":["Pass --force (-f) to skip the prompt when pruning non-interactively.","If the cancellation is expected behavior in your flow, detect it via the errdefs Cancelled interface rather than treating it as a fatal error.","Pipe 'y' to stdin, or use `yes y | docker builder prune` for interactive automation (prefer -f instead)."],"exampleFix":"# before (prompts and you answer no)\ndocker builder prune\n# after — skip the confirmation\ndocker builder prune -f","handlingStrategy":"type-guard","validationCode":"// Non-interactive invocation: pass -f to avoid the prompt entirely.\n// (No code path needed; flag-based.)","typeGuard":"// cancelledErr implements the containerd errdefs Cancelled marker interface.\n// Detect cancellation instead of treating it as a hard failure:\nimport \"github.com/containerd/errdefs\"\nif errdefs.IsCanceled(err) { /* user declined; not fatal */ }","tryCatchPattern":"out, output, err := runPrune(ctx, cli, opts)\nif err != nil {\n    var cancelled interface{ Cancelled() }\n    if errors.As(err, &cancelled) { /* user declined the prune prompt; handle gracefully */ return nil }\n    return err\n}","preventionTips":["Pass --force/-f in scripts and CI to skip prompts.","Treat cancelledErr as expected (not an error) via the Cancelled() interface.","Do not assert a zero exit on user-initiated cancellation."],"tags":["builder","prune","cancellation","interactive"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}