{"record":{"id":"0ca229cf4857dbbe","repo":"gohugoio/hugo","slug":"with-2-arguments-the-first-must-be-a-slice-of-rep","errorCode":null,"errorMessage":"with 2 arguments, the first must be a slice of replacement pairs, got %T","messagePattern":"with 2 arguments, the first must be a slice of replacement pairs, got %T","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/strings/strings.go","lineNumber":277,"sourceCode":"\n// ReplacePairs returns a copy of a string with multiple replacements performed\n// in a single pass. The last argument is the source string. Preceding arguments\n// are old/new string pairs, either as a slice or as individual arguments.\nfunc (ns *Namespace) ReplacePairs(args ...any) (string, error) {\n\tif len(args) < 2 {\n\t\treturn \"\", fmt.Errorf(\"requires at least 2 arguments\")\n\t}\n\n\tss, err := cast.ToStringE(args[len(args)-1])\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tvar p []string\n\tif len(args) == 2 {\n\t\t// slice form: ReplacePairs (slice \"a\" \"b\") \"s\"\n\t\tif !hreflect.IsSlice(args[0]) {\n\t\t\treturn \"\", fmt.Errorf(\"with 2 arguments, the first must be a slice of replacement pairs, got %T\", args[0])\n\t\t}\n\t\tp, err = cast.ToStringSliceE(args[0])\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t}\n\tif p == nil {\n\t\t// inline form: ReplacePairs \"a\" \"b\" \"s\"\n\t\tp = make([]string, len(args)-1)\n\t\tfor i, v := range args[:len(args)-1] {\n\t\t\ts, err := cast.ToStringE(v)\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", err\n\t\t\t}\n\t\t\tp[i] = s\n\t\t}\n\t}\n","sourceCodeStart":259,"sourceCodeEnd":295,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/tpl/strings/strings.go#L259-L295","documentation":"Thrown by strings.ReplacePairs in the 2-argument form when the first argument is not a slice. With exactly 2 args the contract is (sliceOfPairs, sourceString); the code checks hreflect.IsSlice and reports the actual type via %T.","triggerScenarios":"Calling {{ strings.ReplacePairs $x $s }} where $x is a string, map, or single value rather than a slice of pair strings.","commonSituations":"Passing a single inline pair string instead of a slice, passing a map of old->new, or confusing the 2-arg slice form with the inline pair form.","solutions":["Wrap pairs in a slice: strings.ReplacePairs (slice \"a\" \"b\" \"c\" \"d\") $s.","Switch to the inline form for scattered pairs: strings.ReplacePairs \"a\" \"b\" $s.","Ensure the slice elements are string-coercible."],"exampleFix":"// before (string instead of slice):\n{{ strings.ReplacePairs \"a\" $s }}\n// after (slice of pairs):\n{{ strings.ReplacePairs (slice \"a\" \"b\") $s }}","handlingStrategy":"type-guard","validationCode":"{{ if reflect.IsSlice $pairs }}{{ strings.ReplacePairs $pairs $s }}{{ else }}{{ strings.ReplacePairs \"a\" \"b\" $s }}{{ end }}","typeGuard":"{{ if reflect.IsSlice $x }}{{ strings.ReplacePairs $x $s }}{{ else }}{{ warnf \"expected slice\" }}{{ end }}","tryCatchPattern":null,"preventionTips":["In 2-arg form the first arg must be a slice built with 'slice'.","Switch to the inline pair form if you only have scattered pairs.","Use reflect.IsSlice to verify dynamic values."],"tags":["strings","replacepairs","type-error","slice"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}