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

  1. Compare element-wise via a helper or `reflect.DeepEqual` exposed as a FuncMap entry.
  2. Compare lengths or a representative element instead of the whole container.
  3. 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

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


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/d220d304a98b6e0a. Report an issue: GitHub.