{"record":{"id":"3b5dcc3390322731","repo":"gohugoio/hugo","slug":"expected-a-map-a-slice-with-an-even-number-of-ele","errorCode":null,"errorMessage":"expected a map, a slice with an even number of elements, or an even number of scalar values, and each key must be a string","messagePattern":"expected a map, a slice with an even number of elements, or an even number of scalar values, and each key must be a string","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/collections/querify.go","lineNumber":25,"sourceCode":"//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage collections\n\nimport (\n\t\"errors\"\n\t\"net/url\"\n\n\t\"github.com/gohugoio/hugo/common/hmaps\"\n\t\"github.com/spf13/cast\"\n)\n\nvar (\n\terrWrongArgStructure = errors.New(\"expected a map, a slice with an even number of elements, or an even number of scalar values, and each key must be a string\")\n\terrKeyIsEmptyString  = errors.New(\"one of the keys is an empty string\")\n)\n\n// Querify returns a URL query string composed of the given key-value pairs,\n// encoded and sorted by key.\nfunc (ns *Namespace) Querify(params ...any) (string, error) {\n\tif len(params) == 0 {\n\t\treturn \"\", nil\n\t}\n\n\tif len(params) == 1 {\n\t\tswitch v := params[0].(type) {\n\t\tcase map[string]any: // created with collections.Dictionary\n\t\t\treturn mapToQueryString(v)\n\t\tcase hmaps.Params: // project configuration or page parameters\n\t\t\treturn mapToQueryString(v)\n\t\tcase []string:\n\t\t\treturn stringSliceToQueryString(v)","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/tpl/collections/querify.go#L7-L43","documentation":"The `querify` function builds a URL query string from key-value pairs, encoded and sorted by key. This error covers three shapes of bad input: a single argument that is not a map, a `hmaps.Params`, a `[]string`, or a `[]any`; an odd number of scalar variadic arguments (key without value); or a `[]string`/`[]any` slice with an odd element count.","triggerScenarios":"Passing an odd number of scalar args (`{{ querify \"foo\" }}`), passing a single unsupported type (`{{ querify 42 }}`), or passing a slice with an odd length (`{{ querify (slice \"a\" \"1\" \"b\") }}`). The checks fire at querify.go:51 (unsupported single type), querify.go:56 (odd scalar count), and querify.go:96 (odd slice length).","commonSituations":"A developer forgets the value half of a key-value pair, or passes a struct/number where a map or string pairs are expected. Also seen when front matter values are conditionally included, leaving a dangling key after a `del` or absent value.","solutions":["Ensure scalar arguments come in key-value pairs: `{{ querify \"foo\" \"bar\" \"baz\" \"qux\" }}`.","Pass a `dict` or `hmaps.Params` for a single-argument form: `{{ querify (dict \"foo\" \"bar\") }}`.","If using a slice, guarantee an even number of string-castable elements."],"exampleFix":"// before\n{{ querify \"q\" }}\n// after\n{{ querify \"q\" \"hugo\" }}\n// or\n{{ querify (dict \"q\" \"hugo\" \"page\" \"1\") }}","handlingStrategy":"validation","validationCode":"// Validate key-value pairing before querify\n{{ $pairs := slice \"k1\" \"v1\" \"k2\" \"v2\" }}\n{{ if eq (mod (len $pairs) 2) 0 }}\n  {{ querify $pairs }}\n{{ end }}","typeGuard":"func isValidQuerifyInput(params []any) bool {\n    if len(params) == 0 { return true }\n    if len(params) == 1 {\n        switch params[0].(type) {\n        case map[string]any, hmaps.Params, []string, []any: return true\n        default: return false\n        }\n    }\n    return len(params)%2 == 0\n}","tryCatchPattern":null,"preventionTips":["Always pass an even number of scalar arguments (key, value, key, value).","Prefer the single-dict form `querify (dict ...)` for clarity.","Ensure slice elements can be cast to strings."],"tags":["hugo","template","collections","querify","url"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}