gohugoio/hugo · error
must provide a Resource and optionally an options map
Error message
must provide a Resource and optionally an options map
What it means
`openapi3.Unmarshal` (tpl/openapi/openapi3/openapi3.go:73) accepts exactly one or two arguments: a Resource (something implementing UnmarshableResource, typically from `resources.Get`) and an optional options map (currently just `GetRemote` options for resolving remote $refs). Zero arguments or more than two fail this arity check before any parsing happens.
Source
Thrown at tpl/openapi/openapi3/openapi3.go:73
// OpenAPIDocument represents an OpenAPI 3 document.
type OpenAPIDocument struct {
*kopenapi3.T
identityGroup identity.Identity
}
func (o *OpenAPIDocument) GetIdentityGroup() identity.Identity {
return o.identityGroup
}
type unmarshalOptions struct {
// Options passed to resources.GetRemote when resolving remote $ref.
GetRemote map[string]any
}
// Unmarshal unmarshals the given resource into an OpenAPI 3 document.
func (ns *Namespace) Unmarshal(ctx context.Context, args ...any) (*OpenAPIDocument, error) {
if len(args) < 1 || len(args) > 2 {
return nil, errors.New("must provide a Resource and optionally an options map")
}
r := args[0].(resource.UnmarshableResource)
key := r.Key()
if key == "" {
return nil, errors.New("no Key set in Resource")
}
var opts unmarshalOptions
if len(args) > 1 {
optsm, err := hmaps.ToStringMapE(args[1])
if err != nil {
return nil, err
}
if err := mapstructure.WeakDecode(optsm, &opts); err != nil {
return nil, err
}
key += "_" + hashing.HashString(optsm)View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Fetch the spec as a Resource first and pass it: `{{ $api := resources.Get "api/openapi.yaml" | openapi3.Unmarshal }}`.
- If passing options, bundle them into a single map: `{{ $api := openapi3.Unmarshal $r (dict "getRemote" (dict "headers" ...)) }}`.
- Remove any extra positional arguments beyond the Resource and one options map.
Example fix
<!-- before -->
{{ $api := openapi3.Unmarshal "api/openapi.yaml" true }}
<!-- after -->
{{ $r := resources.Get "api/openapi.yaml" }}
{{ $api := openapi3.Unmarshal $r }} Defensive patterns
Strategy: type-guard
Validate before calling
{{ $spec := resources.Get "api/openapi.yaml" }}
{{ if $spec }}
{{ $doc := openapi3.Unmarshal $spec }}
{{ end }} Type guard
{{/* first arg must be a Resource, optional second a map */}}
{{ $isResource := ne $spec nil }}
{{ $optsOK := or (not $opts) (reflect.IsMap $opts) }} Prevention
- Pass the Resource from resources.Get/resources.GetRemote directly, not a string path or file content
- If passing options, make it a dict as the second argument
- Check the resource is non-nil before calling openapi3.Unmarshal
- Don't pipe the spec through transforms that return strings before Unmarshal
When it happens
Trigger: `{{ openapi3.Unmarshal }}` with no arguments, or with three or more, e.g. passing the spec path as a string alongside other values instead of a single Resource plus an options dict.
Common situations: Calling the function with a file path string plus extra args instead of `resources.Get`-ing the spec first; templates written against the pre-0.121 `getJSON`-style APIs; passing options as separate key/value arguments rather than one `dict`.
Related errors
- need at least 2 arguments to append
- no Key set in Resource
- MIME %q not supported
- operator argument must be string type
- can't evaluate the array by no match argument or more than o
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/8afb5842e2524926.json.
Report an issue: GitHub ↗.