{"record":{"id":"14686a8c1a4d9f84","repo":"go-delve/delve","slug":"redirect-error-s-redirected-twice","errorCode":null,"errorMessage":"redirect error: %s redirected twice","messagePattern":"redirect error: (.+?) redirected twice","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/terminal/command.go","lineNumber":1322,"sourceCode":"\t\t\tbreak\n\t\t}\n\t}\n\treturn true, w, redirs, nil\n}\n\nfunc parseOneRedirect(w []string, redirs *[3]string) ([]string, bool, error) {\n\tprefixes := []string{\"<\", \">\", \"2>\"}\n\tnames := []string{\"stdin\", \"stdout\", \"stderr\"}\n\tif len(w) >= 2 {\n\t\tif slices.Contains(prefixes, w[len(w)-2]) {\n\t\t\tw[len(w)-2] += w[len(w)-1]\n\t\t\tw = w[:len(w)-1]\n\t\t}\n\t}\n\tfor i, prefix := range prefixes {\n\t\tif strings.HasPrefix(w[len(w)-1], prefix) {\n\t\t\tif redirs[i] != \"\" {\n\t\t\t\treturn nil, false, fmt.Errorf(\"redirect error: %s redirected twice\", names[i])\n\t\t\t}\n\t\t\tredirs[i] = w[len(w)-1][len(prefix):]\n\t\t\treturn w[:len(w)-1], true, nil\n\t\t}\n\t}\n\treturn w, false, nil\n}\n\nfunc printcontextNoState(t *Term) {\n\tstate, _ := t.client.GetState()\n\tif state == nil || state.CurrentThread == nil {\n\t\treturn\n\t}\n\tprintcontext(t, state)\n}\n\nfunc (c *Commands) rebuild(t *Term, ctx callContext, args string) error {\n\tif ctx.Prefix == revPrefix {","sourceCodeStart":1304,"sourceCodeEnd":1340,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/terminal/command.go#L1304-L1340","documentation":"parseOneRedirect extracts stdin/stdout/stderr redirections (<, >, 2>) from the tail of a restart command line, storing each target in a [3]string. Each stream may be redirected at most once; if the same prefix appears twice (already recorded in redirs[i]), the command is rejected with 'redirect error: %s redirected twice'.","triggerScenarios":"`restart prog > a > b` or `restart prog < in1 < in2` or `restart prog 2> x 2> y` — the same stream prefix encountered twice in parseNewArgv's redirect-extraction loop.","commonSituations":"Users assume shell-like `>>` appending or chaining works and write `> file1 > file2`; scripted restart commands built programmatically concatenate two redirect specs; copy-pasting a shell command line that legitimately redirects a stream twice.","solutions":["Keep at most one redirect per stream: `restart prog > out.txt` not `> a > b`.","Merge the two targets: pick the single file you actually want per stream.","Remember stdin has only one '<'; stderr only one '2>' per command line.","If you need append behavior, this parser does not support `>>`; write to a fresh file or handle appending outside Delve."],"exampleFix":"// before\nrestart myprog > out.log > out2.log\n// error: redirect error: stdout redirected twice\n\n// after\nrestart myprog > out.log","handlingStrategy":"validation","validationCode":"// Ensure each redirect prefix appears at most once before invoking restart\nfunc hasDuplicateRedirects(args string) bool {\n    for _, p := range []string{\"<\", \">\", \"2>\"} {\n        if strings.Count(args, p) > 1 {\n            return true\n        }\n    }\n    return false\n}\n// if hasDuplicateRedirects(args) { fix args first }","typeGuard":null,"tryCatchPattern":"if err := cmd.Execute(\"restart \"+args); err != nil {\n    if strings.Contains(err.Error(), \"redirected twice\") {\n        fmt.Fprintln(os.Stderr, \"each of stdin/stdout/stderr may be redirected at most once\")\n    }\n}","preventionTips":["Use one redirect per stream: single <, >, and 2> per restart command.","Do not chain `> a > b`; choose a single target file.","Remember Delve's parser is not a shell: no >>, no pipes.","When generating restart strings in scripts, build redirects from a map keyed by stream to guarantee uniqueness."],"tags":["terminal","io-redirection","argument-parsing","delve"],"backgroundTag":"duplicate-redirect","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}