{"record":{"id":"a9233853316eebe6","repo":"gohugoio/hugo","slug":"s-is-a-method-of-type-s-but-only-returns-an-erro","errorCode":null,"errorMessage":"%s is a method of type %s but only returns an error type","messagePattern":"(.+?) is a method of type (.+?) but only returns an error type","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/collections/where.go","lineNumber":349,"sourceCode":"\t\targs := []reflect.Value{objPtr}\n\t\tnum := mt.Type.NumIn()\n\t\tmaxNumIn := 1\n\t\tif num > 1 && hreflect.IsContextType(mt.Type.In(1)) {\n\t\t\targs = append(args, ctx)\n\t\t\tmaxNumIn = 2\n\t\t}\n\n\t\tswitch {\n\t\tcase mt.PkgPath != \"\":\n\t\t\treturn zero, fmt.Errorf(\"%s is an unexported method of type %s\", elemName, typ)\n\t\tcase mt.Type.NumIn() > maxNumIn:\n\t\t\treturn zero, fmt.Errorf(\"%s is a method of type %s but requires more than %d parameter\", elemName, typ, maxNumIn)\n\t\tcase mt.Type.NumOut() == 0:\n\t\t\treturn zero, fmt.Errorf(\"%s is a method of type %s but returns no output\", elemName, typ)\n\t\tcase mt.Type.NumOut() > 2:\n\t\t\treturn zero, fmt.Errorf(\"%s is a method of type %s but returns more than 2 outputs\", elemName, typ)\n\t\tcase mt.Type.NumOut() == 1 && mt.Type.Out(0).Implements(errorType):\n\t\t\treturn zero, fmt.Errorf(\"%s is a method of type %s but only returns an error type\", elemName, typ)\n\t\tcase mt.Type.NumOut() == 2 && !mt.Type.Out(1).Implements(errorType):\n\t\t\treturn zero, fmt.Errorf(\"%s is a method of type %s returning two values but the second value is not an error type\", elemName, typ)\n\t\t}\n\t\tres := mt.Func.Call(args)\n\t\tif len(res) == 2 && !res[1].IsNil() {\n\t\t\treturn zero, fmt.Errorf(\"error at calling a method %s of type %s: %s\", elemName, typ, res[1].Interface().(error))\n\t\t}\n\t\treturn res[0], nil\n\t}\n\n\t// elemName isn't a method so next start to check whether it is\n\t// a struct field or a map value. In both cases, it mustn't be\n\t// a nil value\n\tif isNil {\n\t\treturn zero, fmt.Errorf(\"can't evaluate a nil pointer of type %s by a struct field or map key name %s\", typ, elemName)\n\t}\n\tobj = reflect.Indirect(obj)\n\tswitch obj.Kind() {","sourceCodeStart":331,"sourceCodeEnd":367,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/tpl/collections/where.go#L331-L367","documentation":"When a method returns exactly one value and that value implements the `error` interface, `evaluateSubElem` (where.go:348-349) rejects it. A sole error return gives no usable value to compare, so using it as a where key is meaningless.","triggerScenarios":"`{{ where $items \"Validate\" \"==\" nil }}` against `func (i) Validate() error`.","commonSituations":"Trying to filter a collection to valid/invalid items by calling a validator method directly; misunderstanding that `where` needs a value, not a status-only return.","solutions":["Pre-filter the slice in Go before handing it to the template, producing a `Valid bool` field.","Add a method returning the validation result as a non-error value (e.g. `IsValid() bool`).","Compute and store validity as a field during data preparation."],"exampleFix":"// before\n{{ where $items \"Validate\" \"==\" nil }}  {{/* Validate() error */}}\n// after\n{{ where $items \"IsValid\" \"==\" true }}  {{/* IsValid() bool */}}","handlingStrategy":"validation","validationCode":"// Go-side: a sole-error return is unusable as a where key\nmt, ok := reflect.TypeOf(item).MethodByName(name)\nif ok && mt.Type.NumOut() == 1 {\n    ok = !mt.Type.Out(0).Implements(reflect.TypeFor[error]())\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Don't use validator (error-only) methods as `where` keys.","Expose validity as `IsValid() bool` instead.","Keep error returns paired with a value, or stand alone only outside templates."],"tags":["hugo","go-templates","where","reflection","method-signature","error-handling"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}