gohugoio/hugo · error
invalid argument to command: %T
Error message
invalid argument to command: %T
What it means
Returned by commandeer.command in common/hexec/exec.go:495 when building an external command: each argument must be either a string (appended to argv) or a func(*commandeer) option (applied to configure stdio, dir, env, etc.). Any other Go type is rejected with its %T name. This is an internal API-contract error — it indicates a Hugo (or Hugo-embedding) caller passed a wrong-typed value into hexec, not a user configuration mistake.
Source
Thrown at common/hexec/exec.go:495
name string
fullyQualifiedName string
env []string
}
func (c *commandeer) command(arg ...any) (*cmdWrapper, error) {
if c == nil {
return nil, nil
}
var args []string
for _, a := range arg {
switch v := a.(type) {
case string:
args = append(args, v)
case func(*commandeer):
v(c)
default:
return nil, fmt.Errorf("invalid argument to command: %T", a)
}
}
var bin string
if c.fullyQualifiedName != "" {
bin = c.fullyQualifiedName
} else {
var err error
bin, err = exec.LookPath(c.name)
if err != nil {
return nil, &NotFoundError{
name: c.name,
method: "in PATH",
}
}
}
outerr := &bytes.Buffer{}View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Convert every command argument to a string before passing it to the hexec command builder (e.g. cast numeric values with cast.ToString).
- If passing options, ensure they are the func(*commandeer) option type (hexec.WithStdout, WithDir, etc.), not other structs.
- If you hit this as an end user of stock Hugo, report it as a bug with the command/template that triggered it.
Example fix
// before
runner, err := ex.command("--port", 8080)
// after
runner, err := ex.command("--port", strconv.Itoa(8080)) Defensive patterns
Strategy: type-guard
Type guard
// Only strings and hexec option types are valid command args
func validArg(a any) bool {
switch a.(type) {
case string, hexec.Option: // e.g. WithEnviron, WithStdout, WithDir
return true
}
return false
} Prevention
- When calling hexec.Exec.New/Npx from code, pass args as strings and options via the provided With* helpers, never raw ints/structs
- Convert values with fmt.Sprintf/strconv before appending to the arg list
- Keep argument construction in one helper so the type contract is enforced in a single place
When it happens
Trigger: Calling Exec.New/Npx-style runners with an arg that is neither string nor func(*commandeer) — e.g. passing an int, []string, or fmt.Stringer directly instead of converting to string first.
Common situations: Development of Hugo itself or programs embedding hugolib that construct hexec commands; template-driven pipelines that somehow feed non-string args into an external command builder; regressions after refactoring argument plumbing.
Related errors
- conf must be set
- npm pack: failed to marshal package.json with updated worksp
- npm pack: unsupported workspaces type %T
- arguments to symdiff must be slices or arrays
- expected template, but none provided
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/6085e5373b8db7ed.json.
Report an issue: GitHub ↗.