Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/about/release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ The current members of the MkDocs-NG team.

* [@shenxianpeng](https://github.com/shenxianpeng)

## Version 1.7.2 (Unreleased)

### Fixed

* Fix malformed URLs (e.g., unterminated IPv6 literals) crashing the entire build. #45

## Version 1.7.1 (2026-04-25)

### Fixed
Expand Down
15 changes: 14 additions & 1 deletion mkdocs/structure/pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,20 @@ def _possible_target_uris(
tried.add(guess)

def path_to_url(self, url: str) -> str:
scheme, netloc, path, query, anchor = urlsplit(url)
try:
scheme, netloc, path, query, anchor = urlsplit(url)
except ValueError as e:
# The URL parser raised on a malformed link target — for example
# `[click here](http://[::1)`. Per mkdocs#3939, a single bad
# link should not crash the entire build. Log a warning that
# mentions the file and the offending URL, then leave the link
# text untouched in the rendered HTML so the rest of the page
# still builds.
log.warning(
f"Doc file '{self.file.src_uri}' contains an invalid URL '{url}': {e}. "
"The link is being left unchanged."
)
return url

absolute_link = None
warning_level, warning = 0, ""
Expand Down
22 changes: 22 additions & 0 deletions mkdocs/tests/build_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,28 @@ def on_page_context(*args, **kwargs):

# Test build.build

@tempdir(files={"index.md": "[click here](http://[::1)\n"})
@tempdir()
def test_build_warns_and_continues_on_invalid_link_url(self, site_dir, docs_dir):
# Regression for mkdocs/mkdocs#3939: a single markdown link with a
# malformed URL (e.g. an unterminated IPv6 literal) used to crash
# the entire build with `ValueError: Invalid IPv6 URL`. Per the
# maintainer's direction on the issue, mkdocs should now log a
# warning that names the file and the offending URL and keep
# building.
cfg = load_config(docs_dir=docs_dir, site_dir=site_dir, nav=["index.md"])
with self.assertLogs("mkdocs", level="WARNING") as cm:
build.build(cfg)
warning_messages = [
r.getMessage() for r in cm.records if r.levelname == "WARNING"
]
self.assertTrue(
any("'index.md'" in m and "http://[::1" in m for m in warning_messages),
f"Expected a warning naming index.md and the bad URL, got: {warning_messages}",
)
# The page was still produced.
self.assertPathIsFile(site_dir, "index.html")

@tempdir(
files={
"index.md": "page content",
Expand Down
Loading