{"record":{"id":"c3384fa8e6f192aa","repo":"docker/cli","slug":"cowardly-refusing-to-export-to-a-terminal-specify","errorCode":null,"errorMessage":"cowardly refusing to export to a terminal, specify a file path","messagePattern":"cowardly refusing to export to a terminal, specify a file path","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/command/context/export.go","lineNumber":40,"sourceCode":"\t\t\tvar dest string\n\t\t\tif len(args) == 2 {\n\t\t\t\tdest = args[1]\n\t\t\t} else {\n\t\t\t\tdest = contextName + \".dockercontext\"\n\t\t\t}\n\t\t\treturn runExport(dockerCLI, contextName, dest)\n\t\t},\n\t\tValidArgsFunction:     completeContextNames(dockerCLI, 1, true),\n\t\tDisableFlagsInUseLine: true,\n\t}\n}\n\nfunc writeTo(dockerCli command.Cli, reader io.Reader, dest string) error {\n\tvar writer io.Writer\n\tvar printDest bool\n\tif dest == \"-\" {\n\t\tif dockerCli.Out().IsTerminal() {\n\t\t\treturn errors.New(\"cowardly refusing to export to a terminal, specify a file path\")\n\t\t}\n\t\twriter = dockerCli.Out()\n\t} else {\n\t\tf, err := os.OpenFile(dest, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0o600)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tdefer f.Close()\n\t\twriter = f\n\t\tprintDest = true\n\t}\n\tif _, err := io.Copy(writer, reader); err != nil {\n\t\treturn err\n\t}\n\tif printDest {\n\t\tfmt.Fprintf(dockerCli.Err(), \"Written file %q\\n\", dest)\n\t}\n\treturn nil","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cli/command/context/export.go#L22-L58","documentation":"`docker context export` serializes a context into a binary tar archive. When the destination is \"-\" (stdout), writeTo() checks dockerCli.Out().IsTerminal() and refuses to dump raw binary bytes onto an interactive terminal, since that would corrupt the terminal display with control sequences. The guard is a safety measure, not a real I/O failure: it fires only for dest==\"-\" while stdout is a TTY.","triggerScenarios":"Running `docker context export <name> -` from an interactive shell where stdout is attached to a TTY, with no pipe or redirection in place.","commonSituations":"A user copies a pipeline-oriented command (intended as `docker context export ctx - | tar -tv`) but forgets the consuming command, leaving stdout pointing at the terminal; running export interactively to inspect output.","solutions":["Pass a real file path instead of \"-\": `docker context export <name> path.dockercontext`","Redirect stdout to a file: `docker context export <name> - > ctx.tar`","Pipe into a consuming command so stdout is not a TTY: `docker context export <name> - | tar -tv`"],"exampleFix":"// before\ndocker context export myctx -\n// after\ndocker context export myctx myctx.dockercontext\n// or\ndocker context export myctx - > myctx.tar","handlingStrategy":"validation","validationCode":"// Validate destination before exporting to a terminal\ndest := \"-\"\nif dest == \"-\" && dockerCli.Out().IsTerminal() {\n    return fmt.Errorf(\"refusing to export to terminal; pass a file path or redirect stdout\")\n}\n// proceed with store.Export + writeTo","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never pass \"-\" as the export destination in interactive shells","In scripts, always redirect stdout to a file or pipe to a consumer","Detect TTY in wrapper scripts (e.g. `[ -t 1 ]`) before streaming binary output"],"tags":["context","cli","terminal","stdin-stdout"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}