{"id":"5855d5688205cf4f","repo":"gohugoio/hugo","slug":"can-t-extract-relative-path-unknown-prefix","errorCode":null,"errorMessage":"can't extract relative path, unknown prefix","messagePattern":"can't extract relative path, unknown prefix","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/paths/path.go","lineNumber":266,"sourceCode":"\t// Check for the most likely first (faster).\n\tisAllowed := unicode.IsLetter(r) || unicode.IsDigit(r)\n\tisAllowed = isAllowed || r == '.' || r == '/' || r == '\\\\' || r == '_' || r == '#' || r == '+' || r == '~' || r == '-' || r == '@'\n\tisAllowed = isAllowed || unicode.IsMark(r)\n\tisAllowed = isAllowed || (r == '%' && i+2 < len(s) && ishex(s[i+1]) && ishex(s[i+2]))\n\treturn isAllowed\n}\n\n// From https://golang.org/src/net/url/url.go\nfunc ishex(c byte) bool {\n\tswitch {\n\tcase '0' <= c && c <= '9':\n\t\treturn true\n\tcase 'a' <= c && c <= 'f':\n\t\treturn true\n\tcase 'A' <= c && c <= 'F':\n\t\treturn true\n\t}\n\treturn false\n}\n\nvar slashFunc = func(r rune) bool {\n\treturn r == '/'\n}\n\n// Dir behaves like path.Dir without the path.Clean step.\n//\n//\tThe returned path ends in a slash only if it is the root \"/\".\nfunc Dir(s string) string {\n\tdir, _ := path.Split(s)\n\tif len(dir) > 1 && dir[len(dir)-1] == '/' {\n\t\treturn dir[:len(dir)-1]\n\t}\n\treturn dir\n}\n\n// FieldsSlash cuts s into fields separated with '/'.","sourceCodeStart":248,"sourceCodeEnd":284,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/common/paths/path.go#L248-L284","documentation":"makePathRelative strips one of a set of known base directories (content mounts, etc.) from an absolute path to get the path relative to that root. If the input path doesn't start with any of the candidate directories, Hugo cannot determine which root it belongs to and returns this error along with the unmodified path.","triggerScenarios":"A source file path passed to makePathRelative that has no prefix matching any of the possibleDirectories candidates — e.g. a file resolved outside all configured content directories/module mounts, or path-separator/casing mismatches between the file path and the configured roots.","commonSituations":"Symlinked content directories where the resolved absolute path differs from the configured contentDir; Hugo Modules mounts pointing outside the project; case-differing drive letters or mixed slashes on Windows; running hugo from an unexpected working directory with relative contentDir settings.","solutions":["Check that contentDir and module mounts point at the actual (resolved) directories containing your files; avoid symlinks that escape the project root.","On Windows, ensure consistent casing/drive letters in config paths.","Run hugo from the site root, or pass --source with the correct project path.","If reproducible with plain config, file a Hugo issue including the offending file path."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if !strings.HasPrefix(filepath.Clean(path), filepath.Clean(basePath)) {\n    return fmt.Errorf(\"%s is outside %s\", path, basePath)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure the file lives under the configured content/working dir before asking for a relative path","Normalize both paths (Clean, absolute, consistent separators) before prefix comparison","Symlinked directories are a common cause — resolve symlinks consistently on both sides"],"tags":["hugo","paths","filesystem","modules"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}