charmbracelet/crush · error

%s: --%s requires a value

Error message

%s: --%s requires a value

What it means

This error is thrown by nextArg, the shared helper that fetches args[i+1] for value-taking flags (flagString, flagBool, flagInt, flagFloat, flagJSONObject, flagJSONAny). It fires when a flag that requires exactly one value is the last token on the command line, so no value argument exists. nextArg is called from parseFlagValue, which propagates it up through applyFlags as a usage error.

Source

Thrown at internal/shellconfig/flags.go:185

		v, err := nextArg(args, i, name)
		if err != nil {
			return nil, 0, err
		}
		var parsed any
		if err := json.Unmarshal([]byte(v), &parsed); err != nil {
			return nil, 0, fmt.Errorf("%s: --%s expects valid JSON, got %q: %s", args[0], name, v, err)
		}
		return parsed, i + 2, nil

	default:
		return nil, 0, fmt.Errorf("%s: --%s has unknown flag kind", args[0], name)
	}
}

// nextArg returns args[i+1], erroring if the flag is missing its value.
func nextArg(args []string, i int, flag string) (string, error) {
	if i+1 >= len(args) {
		return "", fmt.Errorf("%s: --%s requires a value", args[0], flag)
	}
	return args[i+1], nil
}

// storeFlag writes a parsed value into target according to spec.op.
func storeFlag(target map[string]any, spec flagSpec, val any) {
	switch spec.op {
	case opSet:
		target[spec.jsonKey] = val
	case opAppend:
		arr, _ := target[spec.jsonKey].([]any)
		target[spec.jsonKey] = append(arr, val)
	case opSetChild:
		if kv, ok := val.([2]string); ok {
			childMap(target, spec.child)[kv[0]] = kv[1]
		}
	case opMergeChild:
		if obj, ok := val.(map[string]any); ok {

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Append the missing value: `--api-key <value>` must always be followed by exactly one token.
  2. Quote the value: `--api-key "$MY_KEY"` and verify MY_KEY is set (`echo ${MY_KEY:?unset}`).
  3. Use ${VAR:?} expansions so the shell aborts instead of silently dropping empty values.
  4. Check the builtin's usage output to confirm which flags take values versus valueless booleans (e.g. --think takes none).

Example fix

// before
provider add anthropic --api-key
// after
provider add anthropic --api-key "$ANTHROPIC_API_KEY"
Defensive patterns

Strategy: validation

Validate before calling

# Ensure the flag is not the last token and its value is non-empty
: "${API_KEY:?API_KEY is unset}"   # shell-level guard
[ -n "$API_KEY" ] || exit 2

Type guard

func hasNextArg(args []string, i int) bool { return i+1 < len(args) }

Try / catch

if err := applyFlags(specs, args, start, target, cmd, stderr); err != nil {
    if strings.Contains(err.Error(), "requires a value") {
        fmt.Fprintln(stderr, "That flag needs a value: --flag VALUE")
    }
    return err
}

Prevention

When it happens

Trigger: Ending a command with a value flag: `provider add x --api-key` (nothing after), or `--model` as the final token; also when shell expansion yields an empty trailing arg that is dropped, e.g. `--api-key $KEY` with KEY unset.

Common situations: Truncating a copied command and dropping the secret/token; unset environment variables expanding to nothing before the flag value; accidentally ordering a value flag last before pressing enter; copy-paste losing the value after a newline.

Related errors


AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29). Data as JSON: /api/errors/7cff62d60b2295dc. Report an issue: GitHub.