{"id":"a1021e946e97d08b","repo":"gohugoio/hugo","slug":"inject-absolute-paths-not-supported-must-be-rela","errorCode":null,"errorMessage":"inject: absolute paths not supported, must be relative to /assets","messagePattern":"inject: absolute paths not supported, must be relative to /assets","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/esbuild/build.go","lineNumber":87,"sourceCode":"\t\treturn api.BuildResult{}, err\n\t}\n\n\tif err := opts.compile(); err != nil {\n\t\treturn api.BuildResult{}, err\n\t}\n\n\tvar err error\n\topts.compiled.Plugins, err = createBuildPlugins(c.rs, assetsResolver, dependencyManager, opts)\n\tif err != nil {\n\t\treturn api.BuildResult{}, err\n\t}\n\n\tif opts.Inject != nil {\n\t\t// Resolve the absolute filenames.\n\t\tfor i, ext := range opts.Inject {\n\t\t\timpPath := filepath.FromSlash(ext)\n\t\t\tif filepath.IsAbs(impPath) {\n\t\t\t\treturn api.BuildResult{}, fmt.Errorf(\"inject: absolute paths not supported, must be relative to /assets\")\n\t\t\t}\n\n\t\t\tm := assetsResolver.resolveComponent(impPath, false)\n\n\t\t\tif m == nil {\n\t\t\t\treturn api.BuildResult{}, fmt.Errorf(\"inject: file %q not found\", ext)\n\t\t\t}\n\n\t\t\topts.Inject[i] = m.Filename\n\n\t\t}\n\n\t\topts.compiled.Inject = opts.Inject\n\n\t}\n\n\tresult := api.Build(opts.compiled)\n","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/internal/js/esbuild/build.go#L69-L105","documentation":"The js.Build option `inject` lets you prepend files to the esbuild bundle (e.g. shims). Hugo resolves inject entries through its /assets component filesystem, so each entry must be a path relative to /assets. Absolute filesystem paths are rejected because they would bypass Hugo's virtual filesystem and module mounts.","triggerScenarios":"Calling `js.Build` (or `js.Batch`) with `inject` containing an absolute path, e.g. `dict \"inject\" (slice \"/home/me/shim.js\")` or a leading-slash path — filepath.IsAbs on the entry returns true and the build aborts before esbuild runs.","commonSituations":"Copying esbuild's own `--inject` docs, which use real filesystem paths; prefixing the entry with a slash thinking it means 'assets root' (on Linux/macOS a leading `/` is absolute); passing paths produced by `.Filename` from a resource.","solutions":["Make the inject path relative to the assets directory: use `\"shims/process.js\"` for assets/shims/process.js — no leading slash.","Move the file to be injected into /assets (or a mounted assets dir) if it lives elsewhere.","If the file comes from a Hugo module, mount it into assets/ and reference the mounted relative path."],"exampleFix":"{{/* before */}}\n{{ $js := resources.Get \"main.js\" | js.Build (dict \"inject\" (slice \"/assets/shims/process.js\")) }}\n{{/* after */}}\n{{ $js := resources.Get \"main.js\" | js.Build (dict \"inject\" (slice \"shims/process.js\")) }}","handlingStrategy":"validation","validationCode":"for _, inj := range opts.Inject {\n    if path.IsAbs(inj) {\n        return fmt.Errorf(\"inject path %q must be relative to /assets\", inj)\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Write js.Build inject entries as assets-relative paths, e.g. \"js/shims.js\", never \"/home/...\"","Keep inject files inside assets/ (or a mounted assets dir)","Document the assets-relative convention in your site params so template authors don't pass absolute paths"],"tags":["hugo","js-build","esbuild","assets","config"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}