gohugoio/hugo · error
%s: invalid state: invalid param type %T for shortcode %q, e
Error message
%s: invalid state: invalid param type %T for shortcode %q, expected a map
What it means
Hugo's shortcode parser detected an internal state inconsistency while collecting named (key=value) parameters: the shortcode's accumulated params field was already assigned a non-map value (typically a positional []any slice from earlier positional args). The parser expected a map[string]any because the current token is a named parameter, but the prior params do not match that type. This indicates the shortcode invocation mixes named and positional parameter styles in a way the parser cannot reconcile.
Source
Thrown at hugolib/shortcode.go:690
}
sc.templ = templ
case currItem.IsInlineShortcodeName():
sc.name = currItem.ValStr(source)
sc.isInline = true
case currItem.IsShortcodeParam():
if !pt.IsValueNext() {
continue
} else if pt.Peek().IsShortcodeParamVal() {
// named params
if sc.params == nil {
params := make(map[string]any)
params[currItem.ValStr(source)] = pt.Next().ValTyped(source)
sc.params = params
} else {
if params, ok := sc.params.(map[string]any); ok {
params[currItem.ValStr(source)] = pt.Next().ValTyped(source)
} else {
return sc, fmt.Errorf("%s: invalid state: invalid param type %T for shortcode %q, expected a map", errorPrefix, params, sc.name)
}
}
} else {
// positional params
if sc.params == nil {
var params []any
params = append(params, currItem.ValTyped(source))
sc.params = params
} else {
if params, ok := sc.params.([]any); ok {
params = append(params, currItem.ValTyped(source))
sc.params = params
} else {
return sc, fmt.Errorf("%s: invalid state: invalid param type %T for shortcode %q, expected a slice", errorPrefix, params, sc.name)
}
}
}
case currItem.IsDone():View on GitHub (pinned to 52c9bd7908)
Solutions
- Audit the failing shortcode invocation and convert all parameters to one style: either all positional (space-separated values) or all named (key="value").
- Check the shortcode template definition (layouts/shortcodes/<name>.html) to confirm which style .Get expects, then match the invocation to it.
- If you need both, redesign the shortcode to accept a single style and derive the rest internally.
- Run hugo --renderToMemory or hugo server and read the error prefix (%s:) to find the exact file/line of the offending invocation.
Example fix
// before
{{< mysc foo bar="baz" >}}
// after (all named)
{{< mysc first="foo" bar="baz" >}}
// or (all positional)
{{< mysc foo baz >}} Defensive patterns
Strategy: validation
Validate before calling
// Before rendering content, lint each shortcode invocation for mixed styles.
// (Conceptual Go check over parsed shortcode tokens.)
func validateShortcodeParams(tokens []scToken) error {
seenNamed, seenPositional := false, false
for _, t := range tokens {
if t.isNamedParam() { seenNamed = true }
if t.isPositional() { seenPositional = true }
if seenNamed && seenPositional {
return fmt.Errorf("shortcode %q mixes named and positional params", tokens[0].name)
}
}
return nil
} Prevention
- Standardize each shortcode template on exactly one parameter style and document it.
- Run hugo in CI to catch shortcode param errors before deploy.
- When editing shortcode invocations, re-read the template to confirm the expected style.
When it happens
Trigger: A shortcode call that interleaves positional and named arguments, e.g. {{< mysc positionalval key="x" >}}, where the first token was parsed as positional (setting sc.params to []any) and a subsequent key=value token is then treated as a named param. The mismatch at shortcode.go:687-690 returns this error.
Common situations: Authoring a shortcode and forgetting to keep a single parameter style; copy-pasting a shortcode invocation and partially editing it to add a key=value while leaving positional values; upgrading Hugo where tokenization rules around params changed.
Related errors
- %s: invalid state: invalid param type %T for shortcode %q, e
- no compatible template found for shortcode %q in %s
- %s: shortcode %q must be closed or self-closed
- failed to process shortcode: %w
- can't divide the value by 0
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/39ceb931a8110bde.
Report an issue: GitHub.