sphinx-doc / sphinx-doc/sphinx

Linkcheck Builder: False Positive "Anchor not found" Errors with Encoded Characters in Fragment Identifiers

Open
#13,620 10 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

type:bug
Dominant language
Python
Stars
8k
Forks
2.6k
PR merge metrics
No merged PRs in 30d

Description

Describe the bug

Linkcheck Builder: False Positive "Anchor not found" Errors with Encoded Characters in Fragment Identifiers

Problem Description

The Sphinx linkcheck builder incorrectly reports "Anchor not found" errors for URLs with encoded characters in fragment identifiers (anchors), despite these URLs working correctly in web browsers.

Current Behavior

When encountering a URL with percent-encoded characters in the anchor/fragment (e.g., https://example.com/page#standard-input%2Foutput-stdio), the linkcheck builder:

  1. Extracts the fragment: standard-input%2Foutput-stdio
  2. Decodes it to: standard-input/output-stdio
  3. Searches for an HTML element with id="standard-input/output-stdio" or name="standard-input/output-stdio"
  4. Reports a broken link when the element isn't found
Expected Behavior

The linkcheck builder should recognize URLs with encoded characters in fragments that work in browsers. This includes cases where:

  1. The HTML contains the encoded form in the id attribute: id="standard-input%2Foutput-stdio"
  2. The browser handles the URL correctly through its own anchor matching rules

Example

URL being checked:

https://example.com/page#standard-input%2Foutput-stdio

Sphinx error:

broken link: Anchor 'standard-input/output-stdio' not found

Actual HTML in target page:

<element id="standard-input%2Foutput-stdio">...</element>

This URL works correctly in web browsers but fails in Sphinx linkcheck.

Affected Code

The issue appears to be in the following modules:

  • sphinx/builders/linkcheck.py in HyperlinkAvailabilityCheckWorker._check_uri()
  • sphinx/builders/linkcheck.py in AnchorCheckParser.handle_starttag()

Impact

This issue causes false positive "broken link" reports in documentation that references modern web pages with encoded characters in anchor IDs, leading to:

  • Failed CI/CD pipelines due to false positive link checks
  • Documentation teams needing to create workarounds or ignore valid URLs
  • Extra maintenance overhead to verify links manually

Environment Information

sphinx-build --bug-report

Note: Please include the output of this command when filing the actual issue

Possible Solution Approach

Enhance anchor checking to consider both the decoded anchor (current behavior) and the original encoded anchor as valid matches. This would better align with browser behavior while maintaining backward compatibility.

Additional Context

  • Modern web platforms often use URL-safe encodings in element IDs
  • Browsers handle both encoded and decoded fragment matching
  • This impacts documentation referencing web frameworks, APIs, and various technical documentation sites
How to Reproduce

When encountering a URL with percent-encoded characters in the anchor/fragment (e.g., https://example.com/page#standard-input%2Foutput-stdio), the linkcheck builder:

  1. Extracts the fragment: standard-input%2Foutput-stdio
  2. Decodes it to: standard-input/output-stdio
  3. Searches for an HTML element with id="standard-input/output-stdio" or name="standard-input/output-stdio"
  4. Reports a broken link when the element isn't found
Environment Information
Platform:              darwin; (macOS-15.5-arm64-arm-64bit)
Python version:        3.12.7 (main, Oct  8 2024, 14:30:16) [Clang 16.0.0 (clang-1600.0.26.3)])
Python implementation: CPython
Sphinx version:        8.3.0+/fd7eef97b
Docutils version:      0.21.2
Jinja2 version:        3.1.6
Pygments version:      2.19.1
Sphinx extensions

Additional context

I already have a fix implemented that I'd like to contribute via a PR. I've tested this locally and it works for my implementation.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in sphinx/builders/linkcheck.py, reading HyperlinkAvailabilityCheckWorker._check_uri() and AnchorCheckParser.handle_starttag() to trace how encoded fragments are decoded and matched. Done means valid URLs such as standard-input%2Foutput-stdio no longer produce false "Anchor not found" errors while existing anchor checks continue to work.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
documentation, tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.