{"id":"4607a68461f34cf3","repo":"gohugoio/hugo","slug":"s-is-an-unexported-method-of-type-s","errorCode":null,"errorMessage":"%s is an unexported method of type %s","messagePattern":"(.+?) is an unexported method of type (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/collections/where.go","lineNumber":341,"sourceCode":"\tobjPtr := obj\n\tif !hreflect.IsInterfaceOrPointer(objPtr.Kind()) && objPtr.CanAddr() {\n\t\tobjPtr = objPtr.Addr()\n\t}\n\n\tmt := hreflect.GetMethodByNameForType(objPtr.Type(), elemName)\n\tif mt.Func.IsValid() {\n\t\t// Receiver is the first argument.\n\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","sourceCodeStart":323,"sourceCodeEnd":359,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/tpl/collections/where.go#L323-L359","documentation":"evaluateSubElem found a method matching the key name on the element's type, but the method has a non-empty PkgPath, meaning it is unexported (lowercase). Go reflection cannot call unexported methods, so Hugo rejects the key rather than attempting a call that would panic.","triggerScenarios":"`where $collection \"someMethod\" ...` where the element type (often a custom struct passed via a module or theme's Go code, or a Hugo internal type) has a lowercase method of that exact name; casing mistakes like using `permalink` when the type only exposes it unexported.","commonSituations":"Template authors guessing at method names with lowercase spelling; copying JSON-style lowercase field names into `where` keys when the underlying Go type uses exported CamelCase methods (`Title`, `Permalink`).","solutions":["Use the exported (capitalized) method or field name, e.g. `\"Title\"` not `\"title\"`.","Check Hugo's Page/Resource docs for the correct exported accessor name.","If the data is a map, ensure the map key casing matches exactly instead of relying on a method."],"exampleFix":"<!-- before -->\n{{ range where .Site.RegularPages \"kind\" \"section\" }}\n<!-- after -->\n{{ range where .Site.RegularPages \"Kind\" \"section\" }}","handlingStrategy":"validation","validationCode":"// Go-side: export the method before exposing the type to templates\n// reflect check: m, ok := reflect.TypeOf(v).MethodByName(\"Name\"); ok && m.IsExported()","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only reference exported (capitalized) methods in where key paths","When passing custom Go types into Hugo templates, export any method templates need","Remember key lookup falls back to methods; a lowercase name will never resolve"],"tags":["hugo","templates","where","reflection","unexported"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}