{"record":{"id":"f4193f26cb033b3c","repo":"docker/cli","slug":"containers-prune-has-been-cancelled","errorCode":null,"errorMessage":"containers prune has been cancelled","messagePattern":"containers prune has been cancelled","errorType":"console","errorClass":"cancelledErr","httpStatus":null,"severity":"info","filePath":"cli/command/container/prune.go","lineNumber":107,"sourceCode":"\t\t\tout.WriteString(id + \"\\n\")\n\t\t}\n\t\tspaceReclaimed = res.Report.SpaceReclaimed\n\t}\n\n\treturn spaceReclaimed, out.String(), nil\n}\n\ntype cancelledErr struct{ error }\n\nfunc (cancelledErr) Cancelled() {}\n\n// pruneFn calls the Container Prune API for use in \"docker system prune\",\n// and returns the amount of space reclaimed and a detailed output string.\nfunc pruneFn(ctx context.Context, dockerCLI command.Cli, options pruner.PruneOptions) (uint64, string, error) {\n\tif !options.Confirmed {\n\t\t// Dry-run: perform validation and produce confirmation before pruning.\n\t\tconfirmMsg := \"all stopped containers\"\n\t\treturn 0, confirmMsg, cancelledErr{errors.New(\"containers prune has been cancelled\")}\n\t}\n\treturn runPrune(ctx, dockerCLI, pruneOptions{\n\t\tforce:  true,\n\t\tfilter: options.Filter,\n\t})\n}\n","sourceCodeStart":89,"sourceCodeEnd":114,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cli/command/container/prune.go#L89-L114","documentation":"Returned by pruneFn (the container pruner plugged into 'docker system prune') when options.Confirmed is false. This is the dry-run path: pruneFn emits a confirmation message and a cancelledErr so the system-prune aggregator knows pruning was not actually executed. It is structurally identical to the standalone prune cancellation but flows through the system pruner.","triggerScenarios":"Running `docker system prune` without --force and declining confirmation, or invoking pruneFn programmatically with Confirmed=false. The dry-run branch at prune.go:104-108 returns this.","commonSituations":"System prune in interactive mode where the user aborts. Custom orchestration calling the pruner with Confirmed=false to preview what would be removed.","solutions":["Pass Confirmed=true (or use `docker system prune -f`) to actually prune.","Detect the Cancelled() interface on the returned error to distinguish abort from real failure.","Treat the returned confirmation message as the dry-run output rather than an error in callers."],"exampleFix":"// before\ndocker system prune   # user declined\n\n// after\ndocker system prune -f","handlingStrategy":"try-catch","validationCode":"// For programmatic use, set Confirmed=true to actually prune.\noptions.Confirmed = true","typeGuard":"// cancelledErr implements Cancelled(); detect via interface assertion.\nfunc isCancelled(err error) bool {\n    var c interface{ Cancelled() }\n    return errors.As(err, &c)\n}","tryCatchPattern":"space, out, err := pruneFn(ctx, cli, pruneOpts)\nif err != nil {\n    var c interface{ Cancelled() }\n    if errors.As(err, &c) {\n        // dry-run / declined — `out` holds the confirmation message\n        log.Println(\"dry-run:\", out)\n        return nil\n    }\n    return err\n}","preventionTips":["Treat pruneFn with Confirmed=false as a dry-run preview, not an execution.","Always set Confirmed=true when you intend to actually remove resources.","Surface the returned confirmation string as the dry-run output in tooling."],"tags":["prune","system-prune","user-cancellation","dry-run"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}