{"record":{"id":"6610225e4ea20784","repo":"nektos/act","slug":"valid-streams-are-stdin-stdout-and-stderr","errorCode":null,"errorMessage":"valid streams are STDIN, STDOUT and STDERR","messagePattern":"valid streams are STDIN, STDOUT and STDERR","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/container/docker_cli.go","lineNumber":1146,"sourceCode":"\t\tif isValid := validator(split[2]); !isValid {\n\t\t\treturn val, fmt.Errorf(\"bad mode specified: %s\", mode)\n\t\t}\n\t\tval = fmt.Sprintf(\"%s:%s:%s\", split[0], containerPath, mode)\n\t}\n\n\tif !path.IsAbs(containerPath) {\n\t\treturn val, fmt.Errorf(\"%s is not an absolute path\", containerPath)\n\t}\n\treturn val, nil\n}\n\n// validateAttach validates that the specified string is a valid attach option.\nfunc validateAttach(val string) (string, error) {\n\ts := strings.ToLower(val)\n\tif slices.Contains([]string{\"stdin\", \"stdout\", \"stderr\"}, s) {\n\t\treturn s, nil\n\t}\n\treturn val, errors.New(\"valid streams are STDIN, STDOUT and STDERR\")\n}\n\nfunc toNetipAddrSlice(ips []string) []netip.Addr {\n\tif len(ips) == 0 {\n\t\treturn nil\n\t}\n\tnetIPs := make([]netip.Addr, 0, len(ips))\n\tfor _, ip := range ips {\n\t\taddr, err := netip.ParseAddr(ip)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tnetIPs = append(netIPs, addr)\n\t}\n\treturn netIPs\n}\n","sourceCodeStart":1128,"sourceCodeEnd":1163,"githubUrl":"https://github.com/nektos/act/blob/4f411281417e88660bea1c1a1749aa71ae0bd60f/pkg/container/docker_cli.go#L1128-L1163","documentation":"validateAttach checks each --attach value (lowercased) against the set {stdin, stdout, stderr}; anything else returns 'valid streams are STDIN, STDOUT and STDERR'. Attach options tell Docker which standard streams to hook up for the container, and those three are the only streams that exist, so the parser rejects unknown values early instead of sending an invalid request to the daemon.","triggerScenarios":"A container options string like 'options: --attach logs' or '--attach STDIN,logs' where any element is not stdin/stdout/stderr (case-insensitive). Also values mangled by YAML quoting or shell-like splitting, e.g. '--attach stdin ' with a trailing token.","commonSituations":"Confusing --attach with --log-driver or --publish; passing a file/device name instead of a stream name; copy-paste from docker-compose 'attach' keys that expect a list and getting the syntax wrong in a single-line options string.","solutions":["Use only stdin, stdout, or stderr (any case): '--attach stderr'.","Remove the --attach flag entirely if you did not intend it — act already wires up stdout/stderr for logging.","Check the options string for typos introduced by YAML folding or quote stripping."],"exampleFix":"# before\ncontainer:\n  image: node:20\n  options: --attach logs\n\n# after\ncontainer:\n  image: node:20\n  options: --attach stderr","handlingStrategy":"validation","validationCode":"package main\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\nfunc validateAttachOptions(options string) error {\n\tfields := strings.Fields(options)\n\tfor i, f := range fields {\n\t\tif f != \"--attach\" {\n\t\t\tcontinue\n\t\t}\n\t\tif i+1 >= len(fields) {\n\t\t\treturn fmt.Errorf(\"--attach requires a value\")\n\t\t}\n\t\tswitch strings.ToLower(fields[i+1]) {\n\t\tcase \"stdin\", \"stdout\", \"stderr\":\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"--attach %s invalid: only stdin/stdout/stderr allowed\", fields[i+1])\n\t\t}\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":"if err := runJob(ctx); err != nil {\n    if strings.Contains(err.Error(), \"valid streams are STDIN, STDOUT and STDERR\") {\n        return errors.New(\"remove or correct the --attach value in container options (stdin|stdout|stderr only)\")\n    }\n    return err\n}","preventionTips":["Use only stdin/stdout/stderr (case-insensitive) with --attach.","Remember act already attaches stdout/stderr for logging; --attach is rarely needed.","Do not confuse --attach with --log-driver or --publish."],"tags":["docker","attach","container-options","validation"],"backgroundTag":null,"analyzedSha":"4f411281417e88660bea1c1a1749aa71ae0bd60f","analyzedAt":"2026-08-15T09:19:46.307Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}