go-delve/delve · error

illegal commandline '%s'

Error message

illegal commandline '%s'

What it means

parseNewArgv parses the optional new program arguments given to the 'restart' command in the Delve terminal. The string is tokenized by argv.Argv into a slice of command lines (slices of words); a legal restart argument is exactly one command line. When the tokenizer produces zero or more than one command line, Delve cannot map it onto a single new argv, so it rejects the whole input with 'illegal commandline'.

Source

Thrown at pkg/terminal/command.go:1283

		fmt.Fprintf(t.stdout, "Discarded %s at %s: %v\n", formatBreakpointName(discarded[i].Breakpoint, false), t.formatBreakpointLocation(discarded[i].Breakpoint), discarded[i].Reason)
	}
	return nil
}

func parseNewArgv(args string) (resetArgs bool, newArgv []string, newRedirects [3]string, err error) {
	if args == "" {
		return false, nil, [3]string{}, nil
	}
	v, err := argv.Argv(args,
		func(s string) (string, error) {
			return "", fmt.Errorf("Backtick not supported in '%s'", s)
		},
		nil)
	if err != nil {
		return false, nil, [3]string{}, err
	}
	if len(v) != 1 {
		return false, nil, [3]string{}, fmt.Errorf("illegal commandline '%s'", args)
	}
	w := v[0]
	if len(w) == 0 {
		return false, nil, [3]string{}, nil
	}
	if w[0] == "-noargs" {
		if len(w) > 1 {
			return false, nil, [3]string{}, errors.New("too many arguments to restart")
		}
		return true, nil, [3]string{}, nil
	}
	redirs := [3]string{}
	for len(w) > 0 {
		var found bool
		var err error
		w, found, err = parseOneRedirect(w, &redirs)
		if err != nil {
			return false, nil, [3]string{}, err

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Re-run restart with a single, simply-quoted command line (no pipes, semicolons, or backticks), e.g. `restart arg1 "arg two"`.
  2. Remove any backtick substitution; it is explicitly unsupported here.
  3. Check quoting: ensure quotes are balanced and there is exactly one command (one argv vector) in the argument string.
  4. If you need shell features (pipes, redirection chains), launch the program outside Delve and attach, or precompute the args.

Example fix

// before
restart foo | grep bar
// error: illegal commandline 'foo | grep bar'

// after
restart foo
// run grep on the output outside the debugger
Defensive patterns

Strategy: validation

Validate before calling

// Validate a restart args string before passing it to the restart command
func validRestartArgs(args string) bool {
    if args == "" {
        return true
    }
    if strings.ContainsAny(args, "`;|") {
        return false // backticks unsupported; pipes/semicolons yield multiple argv
    }
    // crude balance check for quotes
    return strings.Count(args, "\"")%2 == 0 && strings.Count(args, "'")%2 == 0
}

Try / catch

// terminal command errors surface as the returned error
if err := cmd.Execute("restart "+args); err != nil {
    if strings.Contains(err.Error(), "illegal commandline") {
        fmt.Fprintf(os.Stderr, "invalid restart args %q: use a single quoted command line\n", args)
    }
}

Prevention

When it happens

Trigger: Running `restart <args>` where args contains unbalanced quotes, backtick-substitution attempts, or tokenizes into multiple command lines (len(v) != 1), e.g. stray semicolons/pipes or an empty-but-nonempty-looking argument string. Called from restartRecorded, restartLive and directly exercised by TestParseNewArgv.

Common situations: Users paste a shell command with pipes/redirects shell-style into restart; quoting from another shell is copied verbatim and breaks argv parsing; an editor/IDE plugin passes a malformed restart args string.

Related errors


AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31). Data as JSON: /api/errors/83f1b9f8cc37de7b. Report an issue: GitHub.