{"record":{"id":"6fbc57c4b87bc528","repo":"docker/cli","slug":"invalid-detach-keys-s-w","errorCode":null,"errorMessage":"invalid detach keys (%s): %w","messagePattern":"invalid detach keys \\((.+?)\\): %w","errorType":"validation","errorClass":"invalidParameterErr","httpStatus":null,"severity":"error","filePath":"cli/command/container/hijack.go","lineNumber":38,"sourceCode":"\n// readCloserWrapper wraps an io.Reader, and implements an io.ReadCloser\n// It calls the given callback function when closed.\ntype readCloserWrapper struct {\n\tio.Reader\n\tcloser func() error\n}\n\n// Close calls back the passed closer function\nfunc (r *readCloserWrapper) Close() error {\n\treturn r.closer()\n}\n\nfunc validateDetachKeys(keys string) error {\n\tif keys == \"\" {\n\t\treturn nil\n\t}\n\tif _, err := term.ToBytes(keys); err != nil {\n\t\treturn invalidParameter(fmt.Errorf(\"invalid detach keys (%s): %w\", keys, err))\n\t}\n\treturn nil\n}\n\n// A hijackedIOStreamer handles copying input to and output from streams to the\n// connection.\ntype hijackedIOStreamer struct {\n\tstreams      command.Streams\n\tinputStream  io.ReadCloser\n\toutputStream io.Writer\n\terrorStream  io.Writer\n\n\tresp client.HijackedResponse\n\n\ttty        bool\n\tdetachKeys string\n}\n","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cli/command/container/hijack.go#L20-L56","documentation":"Returned by validateDetachKeys (hijack.go:38) when term.ToBytes cannot parse the --detach-keys value. Detach keys are converted to a byte sequence; an unparseable specifier (e.g. an unknown key name) produces this error, wrapped by invalidParameter so it is treated as a client-side usage error.","triggerScenarios":"Passing `--detach-keys` with a value term.ToBytes cannot understand: an unrecognized token, malformed escape, or a sequence with trailing garbage. Common in `docker attach`, `docker exec`, `docker run -it`.","commonSituations":"Typo in a key name (e.g. ctrl-p&ctrl-x mistyped), copy-paste of an unsupported sequence, or a config-file detachKeys value from an older/incompatible Docker version.","solutions":["Use the documented format, e.g. --detach-keys=ctrl-p,ctrl-x or a single key like --detach-keys=q.","Check ~/.docker/config.json detachKeys if set globally.","Remove the flag to use the default (ctrl-p ctrl-q)."],"exampleFix":"# before\ndocker attach --detach-keys=ctrl+p&ctrl+x box\n\n# after\ndocker attach --detach-keys=ctrl-p,ctrl-x box","handlingStrategy":"validation","validationCode":"// Validate detach-keys syntax the same way the CLI does:\nimport \"github.com/moby/term\"\nif _, err := term.ToBytes(detachKeys); err != nil {\n    return fmt.Errorf(\"bad --detach-keys %q: %w\", detachKeys, err)\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"invalid detach keys\") {\n    // fall back to the default ctrl-p,ctrl-q by dropping the flag\n}","preventionTips":["Prefer documented tokens like ctrl-p,ctrl-x.","Omit --detach-keys to use the default.","Validate the value before scripting it into many commands."],"tags":["container","terminal","cli","flag-validation","hijack"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}