{"record":{"id":"f6c8d4652aa938a4","repo":"gohugoio/hugo","slug":"failed-to-read-local-ref-q-w","errorCode":null,"errorMessage":"failed to read local ref %q: %w","messagePattern":"failed to read local ref %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/openapi/openapi3/openapi3.go","lineNumber":198,"sourceCode":"\t\t}\n\t\tr.idm.AddIdentity(identity.FirstIdentity(res))\n\t\treturn []byte(content), nil\n\t}\n\n\tvar filename string\n\tif strings.HasPrefix(loc.Path, \"/\") {\n\t\tfilename = loc.Path\n\t} else {\n\t\tfilename = path.Join(r.relBase, loc.Path)\n\t}\n\n\tres := r.ns.resourcesNs.Get(filename)\n\tif res == nil {\n\t\treturn nil, fmt.Errorf(\"local ref %q not found\", loc.String())\n\t}\n\tcontent, err := resources.InternalResourceSourceContent(r.ctx, res)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to read local ref %q: %w\", loc.String(), err)\n\t}\n\tr.idm.AddIdentity(identity.FirstIdentity(res))\n\treturn []byte(content), nil\n}\n","sourceCodeStart":180,"sourceCodeEnd":203,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/tpl/openapi/openapi3/openapi3.go#L180-L203","documentation":"Thrown by the OpenAPI v3 document loader when resolving an external $ref that points to a local file in the Hugo assets filesystem. The resource was found (so the path is valid) but InternalResourceSourceContent failed to read its bytes. The %q placeholder is the ref location and %w wraps the underlying read error.","triggerScenarios":"Calling openapi3.Unmarshal on a Resource whose OpenAPI document contains a $ref (e.g. \"$ref\": \"components/user.yaml\") pointing to another asset file whose content cannot be read at resolution time. Occurs during ResolveRefsIn when IsExternalRefsAllowed is true.","commonSituations":"The referenced asset file is a symlink that was dropped by hugofs.DropSymlinksFs, the resource content is a remote-backed resource whose fetch hasn't completed, the file was deleted/renamed between build passes, or the resource's ReadSeekCloser returns an error. Also seen after upgrading Hugo versions that changed asset path resolution.","solutions":["Verify the referenced asset file actually exists under the assets/ (or layouts/) directory and is readable.","Check the $ref path is relative to the OpenAPI document location, not the project root; the resolver joins r.relBase with loc.Path for non-absolute paths.","Avoid symlinks for referenced OpenAPI fragment files since hugofs drops them; copy the files instead.","Inspect the wrapped %w error to identify whether it is a permissions, missing-content, or fetch issue."],"exampleFix":"// before (broken $ref path):\nopenapi: \"$ref\": \"user.yaml\"\n// after (path relative to the spec's own directory):\nopenapi: \"$ref\": \"components/user.yaml\"","handlingStrategy":"validation","validationCode":"{{ if and (resources.Get $refPath) (not (os.FileExists $refPath)) }}\n  {{ erroridf \"openapi-ref\" \"ref target unreadable: %q\" $refPath }}\n{{ end }}","typeGuard":"// Go-side guard before building the doc:\nif r, ok := ns.Get(refPath); ok && r != nil {\n    if _, err := resources.InternalResourceSourceContent(ctx, r); err != nil { /* skip / warn */ }\n}","tryCatchPattern":null,"preventionTips":["Keep all $ref fragment files as real files (not symlinks) under assets/.","Validate that every local $ref target resolves to a readable resource before publishing.","Pin the OpenAPI source under version control so ref targets cannot drift."],"tags":["openapi","assets","ref-resolution","filesystem"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}