joewalnes/websocketd · error

ambiguous: provided COMMAND and --dir argument, please only

Error message

ambiguous: provided COMMAND and --dir argument, please only specify one

What it means

resolveCommand rejects a command line that specifies both a COMMAND argument and the --dir flag, because the two are mutually exclusive ways to tell websocketd what to run. COMMAND launches a single executable; --dir serves every script in a directory. Specifying both would make the launch target ambiguous, so the CLI fails fast at config-parse time.

Source

Thrown at config.go:201

	for _, key := range strings.Split(passenv, ",") {
		if key == "HTTPS" {
			continue
		}
		if v := os.Getenv(key); v != "" {
			if clean := strings.TrimSpace(newlineCleaner.Replace(v)); clean != "" {
				env = append(env, fmt.Sprintf("%s=%s", key, clean))
			}
		}
	}
	return env
}

// resolveCommand validates and resolves the command to execute.
// Returns the resolved command path and arguments.
func resolveCommand(args []string, scriptDir string) (commandName string, commandArgs []string, err error) {
	if len(args) > 0 {
		if scriptDir != "" {
			return "", nil, fmt.Errorf("ambiguous: provided COMMAND and --dir argument, please only specify one")
		}
		path, lookErr := exec.LookPath(args[0])
		if lookErr != nil {
			return "", nil, fmt.Errorf("unable to locate specified COMMAND '%s' in OS path", args[0])
		}
		return path, args[1:], nil
	}
	return "", nil, nil
}

// resolveScriptDir validates and resolves the script directory path.
func resolveScriptDir(dir string) (string, error) {
	if dir == "" {
		return "", nil
	}
	absDir, err := filepath.Abs(dir)
	if err != nil {
		return "", fmt.Errorf("could not resolve absolute path to dir '%s'", dir)

View on GitHub (pinned to 7a8683dc7f)

Solutions

  1. Remove the --dir flag if you want to run the single COMMAND
  2. Remove the trailing COMMAND arguments and keep --dir to serve all scripts in that directory
  3. If a wrapper always injects --dir, set it conditionally only when no COMMAND is given

Example fix

// before
websocketd --dir=./scripts ./scripts/count.sh
// after
websocketd --dir=./scripts   # serve the whole directory
# or
websocketd ./scripts/count.sh  # run one command
Defensive patterns

Strategy: validation

Validate before calling

args, err := parseFlags(os.Args)
if err != nil {
	log.Fatal(err)
}
if flags.Dir != "" && len(args) > 0 {
	log.Fatal("pass either COMMAND or --dir, not both")
}

Prevention

When it happens

Trigger: Running e.g. `websocketd --dir=./scripts ./scripts/count.sh` — resolveCommand sees len(args)>0 AND scriptDir!="" and returns this error before anything is executed.

Common situations: Copy-pasting an example that uses --dir and appending a script path out of habit; migrating from single-script usage to directory mode (or the reverse) and forgetting to drop the other flag; shell wrapper scripts that always pass --dir while also forwarding a command.

Related errors


AI-assisted analysis of joewalnes/websocketd@7a8683dc7f (2026-09-03). Data as JSON: /api/errors/5c3606d2cf7a5f35. Report an issue: GitHub.