charmbracelet/crush · error

%s: --%s expects an integer, got %q

Error message

%s: --%s expects an integer, got %q

What it means

parseFlagValue validates integer flags via strconv.ParseInt(v, 10, 64). If the value following a flagInt flag isn't a base-10 integer, applyFlags aborts with "<cmd>: --<flag> expects an integer, got %q". This surfaces during crushrc config parsing, before any config is applied.

Source

Thrown at internal/shellconfig/flags.go:134

	case flagBool:
		v, err := nextArg(args, i, name)
		if err != nil {
			return nil, 0, err
		}
		b, err := parseBool(v)
		if err != nil {
			return nil, 0, fmt.Errorf("%s: --%s expects true/false, got %q", args[0], name, v)
		}
		return b, i + 2, nil

	case flagInt:
		v, err := nextArg(args, i, name)
		if err != nil {
			return nil, 0, err
		}
		n, err := strconv.ParseInt(v, 10, 64)
		if err != nil {
			return nil, 0, fmt.Errorf("%s: --%s expects an integer, got %q", args[0], name, v)
		}
		return n, i + 2, nil

	case flagFloat:
		v, err := nextArg(args, i, name)
		if err != nil {
			return nil, 0, err
		}
		f, err := strconv.ParseFloat(v, 64)
		if err != nil {
			return nil, 0, fmt.Errorf("%s: --%s expects a number, got %q", args[0], name, v)
		}
		return f, i + 2, nil

	case flagKeyValue:
		if i+2 >= len(args) {
			return nil, 0, fmt.Errorf("%s: --%s requires a key and value", args[0], name)
		}

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Provide a plain base-10 integer (e.g. 30000 instead of 30s).
  2. Remove commas, units, or 0x prefixes from the value.
  3. Trim whitespace/quotes around the value in the crushrc line.
  4. If the flag truly needs a duration or float, the builtin author should declare it flagFloat or a string flag and parse it in the handler.

Example fix

// before (crushrc)
options --timeout 30s
// after
options --timeout 30
Defensive patterns

Strategy: validation

Validate before calling

func isIntLiteral(v string) bool {
	_, err := strconv.ParseInt(v, 10, 64)
	return err == nil
}

Try / catch

err := cfg.Apply(args)
if err != nil && strings.Contains(err.Error(), "expects an integer") {
	// show cmd+flag and the offending value from the message
}

Prevention

When it happens

Trigger: A crushrc line like `options --timeout 30s` or `--retries three` where the flag was registered as flagInt; passing a float like 1.5 to an integer flag; hex (0x1F) or underscore-formatted numbers that ParseInt(…,10,64) rejects.

Common situations: Users writing durations with units (30s, 5m) for flags that expect plain integers; locale-formatted numbers (1,000); copy-pasted values with trailing whitespace or units.

Related errors


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