gohugoio/hugo · error
non-comparable type %s: %v
Error message
non-comparable type %s: %v
What it means
Raised by `eq` when operands are the same non-basic kind, both non-nil, `canCompare` is true, but the operand's type is not reflect.Comparable (funcs.go:503-505). Go does not permit `==` on slices, maps, or funcs, so the template engine refuses too. Format: `val type`.
Source
Thrown at tpl/internal/go_templates/texttemplate/funcs.go:505
case complexKind:
truth = arg1.Complex() == arg.Complex()
case floatKind:
truth = arg1.Float() == arg.Float()
case intKind:
truth = arg1.Int() == arg.Int()
case stringKind:
truth = arg1.String() == arg.String()
case uintKind:
truth = arg1.Uint() == arg.Uint()
default:
if !canCompare(arg1, arg) {
return false, fmt.Errorf("non-comparable types %s: %v, %s: %v", arg1, arg1.Type(), arg.Type(), arg)
}
if isNil(arg1) || isNil(arg) {
truth = isNil(arg) == isNil(arg1)
} else {
if !arg.Type().Comparable() {
return false, fmt.Errorf("non-comparable type %s: %v", arg, arg.Type())
}
truth = arg1.Interface() == arg.Interface()
}
}
}
if truth {
return true, nil
}
}
return false, nil
}
// ne evaluates the comparison a != b.
func ne(arg1, arg2 reflect.Value) (bool, error) {
// != is the inverse of ==.
equal, err := eq(arg1, arg2)
return !equal, err
}View on GitHub (pinned to 52c9bd7908)
Solutions
- Compare element-wise via a helper or `reflect.DeepEqual` exposed as a FuncMap entry.
- Compare lengths or a representative element instead of the whole container.
- Use `{{eq (printf "%v" .A) (printf "%v" .B)}}` only for diagnostics, not production equality.
Example fix
// before
{{eq .Tags .PrevTags}} // both []string
// after
{{deepEqual .Tags .PrevTags}} // custom FuncMap using reflect.DeepEqual Defensive patterns
Strategy: fallback
Validate before calling
// Use a deep-equal helper instead of eq for slices/maps:
// {{deepEqual .Tags .PrevTags}} // FuncMap: reflect.DeepEqual Type guard
func isComparable(v interface{}) bool {
if v == nil { return false }
t := reflect.TypeOf(v)
return t.Comparable()
} Prevention
- Never use eq on slices, maps, or funcs — Go forbids it.
- Expose reflect.DeepEqual as a FuncMap entry for structural equality.
- Compare lengths or canonicalized forms as a lighter alternative.
When it happens
Trigger: `{{eq .List .Other}}` where both are `[]string`; `{{eq .Map .OtherMap}}`; comparing two function values.
Common situations: Expecting value equality on slices/maps (Go only allows nil-check); comparing pagination slices; deep-equality assumptions from other languages.
Related errors
- incompatible types for comparison: %v and %v
- non-comparable types %s: %v, %s: %v
- invalid type for comparison
- can't index item of type %s
- slice of untyped nil
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/d220d304a98b6e0a.
Report an issue: GitHub.