Skip to content

References to sections in symlinked files can fail #1055

@effigies

Description

@effigies

What version of myst-parser are you using?

4.0.1

What version dependencies are you using?

sphinx 8.2.3
docutils 0.21.2

What operating system are you using?

Linux

Describe the Bug

An explicit, relative link (e.g. [Section title](document.md#section-title)) will produce an error if document.md is a symlink outside the documentation directory.

If document.md is a symlink to, for example, ../README.md, you will get:

/path/to/project/docs/referrer.md:266: WARNING: Unknown source document '/path/to/project/README' [myst.xref_missing]

and the link will fail to render.

This exhibits here:

def resolve_myst_ref_doc(self, node: pending_xref):
"""Resolve a reference, from a markdown link, to another document,
optionally with a target id within that document.
"""
from_docname = node.get("refdoc", self.env.docname)
ref_docname: str = node["reftarget"]
ref_id: str | None = node["reftargetid"]
if ref_docname not in self.env.all_docs:
self.log_warning(
ref_docname,
f"Unknown source document {ref_docname!r}",
MystWarnings.XREF_MISSING,
location=node,
)
node.replace_self(node[0].deepcopy())
return

I believe the source of the node with the bad reftarget is here:

_, abs_path = self.sphinx_env.relfn2path(path_dest, self.sphinx_env.docname)
docname = self.sphinx_env.path2doc(abs_path)
if not docname:
self.create_warning(
f"Could not find document: {abs_path}",
MystWarnings.XREF_MISSING,
line=token_line(token, 0),
append_to=self.current_node,
)
return self.render_link_url(token)
wrap_node = addnodes.pending_xref(
refdomain="doc",
reftarget=docname,
reftargetid=path_id,
refdoc=self.sphinx_env.docname,
reftype="myst",
refexplicit=explicit,
)

And I believe this happens because sphinx_env.relfn2path uses Path.resolve() instead of normalizing a path:

https://github.com/sphinx-doc/sphinx/blob/046151a2d5ae1f00f40e2176c35a50f997afd314/sphinx/environment/__init__.py#L451-L475

I don't know if this issue properly belongs in sphinx, but it only seems to cause problems for a particular style of Markdown link.

Expected Behavior

[Section title](document.md#section-title) should become <a href="document.html#section-title">Section title</a>.

To Reproduce

Using uv:

mkdir docs
cat <<EOF > README.md
# Header

## Section

Text
EOF

uv init --bare --name=reproduction --no-workspace
uv add sphinx myst-parser
uv run sphinx-quickstart --project="Reproduction" --author="Author Name" \
        --no-sep -r '' -l en --extensions myst_parser \
        docs/

ln -s ../README.md docs/description.md

cat <<EOF >> docs/conf.py

myst_heading_anchors = 2
EOF

cat <<EOF > docs/document.md
# Document Title

Explicitly linking to [Section](description.md#section).
EOF

cat <<EOF >> docs/index.rst
   description.md
   document.md
EOF

uv run sphinx-build -b html docs docs/_build/html

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions