{"record":{"id":"ff2e41ea17b6a558","repo":"gohugoio/hugo","slug":"can-t-make-permalink-from-absolute-link-q","errorCode":null,"errorMessage":"can't make permalink from absolute link %q","messagePattern":"can't make permalink from absolute link %q","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"common/paths/url.go","lineNumber":71,"sourceCode":"// MakePermalink combines base URL with content path to create full URL paths.\n// Example\n//\n//\tbase:   http://spf13.com/\n//\tpath:   post/how-i-blog\n//\tresult: http://spf13.com/post/how-i-blog\nfunc MakePermalink(host, plink string) *url.URL {\n\tbase, err := url.Parse(host)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tp, err := url.Parse(plink)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tif p.Host != \"\" {\n\t\tpanic(fmt.Errorf(\"can't make permalink from absolute link %q\", plink))\n\t}\n\n\tbase.Path = path.Join(base.Path, p.Path)\n\tbase.Fragment = p.Fragment\n\tbase.RawQuery = p.RawQuery\n\n\t// path.Join will strip off the last /, so put it back if it was there.\n\thadTrailingSlash := (plink == \"\" && strings.HasSuffix(host, \"/\")) || strings.HasSuffix(p.Path, \"/\")\n\tif hadTrailingSlash && !strings.HasSuffix(base.Path, \"/\") {\n\t\tbase.Path = base.Path + \"/\"\n\t}\n\n\treturn base\n}\n\n// AddContextRoot adds the context root to an URL if it's not already set.\n// For relative URL entries on sites with a base url with a context root set (i.e. http://example.com/mysite),\n// relative URLs must not include the context root if canonifyURLs is enabled. But if it's disabled, it must be set.","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/common/paths/url.go#L53-L89","documentation":"Panicked (not returned) by paths.MakePermalink when the supplied content link `plink` already contains a host component. MakePermalink joins a host base URL with a path; an absolute link would double the host, so it refuses rather than producing a malformed URL.","triggerScenarios":"Calling paths.MakePermalink(host, plink) where plink parses to a *url.URL with a non-empty .Host (e.g. 'https://example.com/post/x' instead of '/post/x').","commonSituations":"Frontmatter `url`/`permalink` fields set to absolute URLs, or content migrations that imported canonical URLs; Hugo's permalink construction then hits this panic during page rendering.","solutions":["Strip the scheme+host from plink before calling; pass only the path portion.","In frontmatter, use relative paths for the `url` field.","If absolute URLs are required downstream, skip MakePermalink and use the link as-is."],"exampleFix":"// before\npaths.MakePermalink(\"https://site.com/\", \"https://site.com/post/x\")\n// after\npaths.MakePermalink(\"https://site.com/\", \"/post/x\")","handlingStrategy":"validation","validationCode":"func isRelativeLink(s string) bool {\n  u, err := url.Parse(s); if err != nil { return false }\n  return u.Host == \"\"\n}","typeGuard":"func isRelativeLink(s string) bool { u, err := url.Parse(s); return err == nil && u.Host == \"\" }","tryCatchPattern":null,"preventionTips":["Keep frontmatter url/permalink fields relative.","Strip scheme+host from imported canonical URLs during migration.","Wrap MakePermalink calls with a recover() in template pipelines."],"tags":["paths","permalink","url","panic","absolute-link"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}