{"record":{"id":"13f8ea603bcae860","repo":"gohugoio/hugo","slug":"s-is-a-method-of-type-s-returning-two-values-but","errorCode":null,"errorMessage":"%s is a method of type %s returning two values but the second value is not an error type","messagePattern":"(.+?) is a method of type (.+?) returning two values but the second value is not an error type","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/collections/where.go","lineNumber":351,"sourceCode":"\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() {\n\tcase reflect.Struct:\n\t\tft, ok := obj.Type().FieldByName(elemName)","sourceCodeStart":333,"sourceCodeEnd":369,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/tpl/collections/where.go#L333-L369","documentation":"`evaluateSubElem` (where.go:350-351) allows two-return methods only when the second return is an `error`. If a method returns two values but `mt.Type.Out(1)` does not implement the error interface (e.g. `(string, int)`), Hugo cannot disambiguate which value to use and reports it.","triggerScenarios":"`{{ where $items \"Get\" \"==\" \"x\" }}` against `func (i) Get() (string, int)`.","commonSituations":"Reusing a tuple-returning accessor as a where key; a method that returns `(value, count)` or `(value, ok bool)` rather than `(value, error)`.","solutions":["Change the method signature to `(T, error)` to match Hugo's expected idiom.","Provide a dedicated single-value method for the field you want to match.","Filter on a struct field that already exposes the desired value."],"exampleFix":"// before\n{{ where $items \"Get\" \"==\" \"x\" }}  {{/* Get() (string, int) */}}\n// after\n{{ where $items \"Value\" \"==\" \"x\" }}  {{/* Value() string */}}","handlingStrategy":"validation","validationCode":"// Go-side: two returns must be (T, error)\nmt, ok := reflect.TypeOf(item).MethodByName(name)\nif ok && mt.Type.NumOut() == 2 {\n    ok = mt.Type.Out(1).Implements(reflect.TypeFor[error]())\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Adopt the Go idiom (value, error) for two-return template methods.","Avoid (value, ok bool) accessors for template-facing APIs.","Add a lint/test enforcing the (T, error) shape on template methods."],"tags":["hugo","go-templates","where","reflection","method-signature"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}