{"id":"70ad562a17e74c54","repo":"gohugoio/hugo","slug":"can-t-evaluate-an-invalid-value","errorCode":null,"errorMessage":"can't evaluate an invalid value","messagePattern":"can't evaluate an invalid value","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/collections/where.go","lineNumber":314,"sourceCode":"\t\tif svp != nil && smvp != nil {\n\t\t\tre, err := hstrings.GetOrCompileRegexp(*smvp)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif re.MatchString(*svp) {\n\t\t\t\treturn true, nil\n\t\t\t}\n\t\t\treturn false, nil\n\t\t}\n\tdefault:\n\t\treturn false, errors.New(\"no such operator\")\n\t}\n\treturn false, nil\n}\n\nfunc evaluateSubElem(ctx, obj reflect.Value, elemName string) (reflect.Value, error) {\n\tif !obj.IsValid() {\n\t\treturn zero, errors.New(\"can't evaluate an invalid value\")\n\t}\n\n\ttyp := obj.Type()\n\tobj, isNil := hreflect.Indirect(obj)\n\n\t// first, check whether obj has a method. In this case, obj is\n\t// a struct or its pointer. If obj is a struct,\n\t// to check all T and *T method, use obj pointer type Value\n\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()","sourceCodeStart":296,"sourceCodeEnd":332,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/tpl/collections/where.go#L296-L332","documentation":"Raised by evaluateSubElem in Hugo's `where` template function when the reflect.Value it is asked to descend into is invalid (the zero reflect.Value). This happens when a dotted key path references data that doesn't exist at all — reflection cannot inspect a value that was never there. Hugo fails fast rather than silently treating the missing value as a non-match at this stage of sub-element resolution.","triggerScenarios":"Calling `where` (or `Site.Pages.GroupByParam`-style helpers routed through evaluateSubElem) with a dotted key like `where .Site.Data.people \"address.city\" \"Oslo\"` where an intermediate element (`address`) is a missing map key returning an invalid reflect.Value, or the collection contains untyped nil interface entries.","commonSituations":"Data files (data/*.yaml/json) where some records omit a nested field used in the where key path; front matter params missing on some pages; typo in the nested key path; iterating heterogeneous slices where some elements are nil interfaces.","solutions":["Check the key path spelling in the `where` call against the actual data structure.","Ensure every record in the collection has the nested field, or pre-filter: `where (where $c \"address\" \"!=\" nil) \"address.city\" \"Oslo\"`.","Normalize your data files so all entries share the same schema."],"exampleFix":"<!-- before -->\n{{ range where .Site.Data.people \"address.city\" \"Oslo\" }}\n<!-- after: filter out entries missing the nested map first -->\n{{ $withAddr := where .Site.Data.people \"address\" \"!=\" nil }}\n{{ range where $withAddr \"address.city\" \"Oslo\" }}","handlingStrategy":"validation","validationCode":"{{/* skip nil/invalid entries before where */}}\n{{ $items := slice }}\n{{ range $c }}{{ if . }}{{ $items = $items | append . }}{{ end }}{{ end }}\n{{ $r := where $items \"Field\" \"v\" }}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Filter out nil elements from the collection before calling where","Ensure map values or struct fields referenced by the key actually hold values (not nil interfaces)","When building slices dynamically, never append nil placeholders"],"tags":["hugo","templates","where","reflection","data-files"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}