Skip to content

fix(markdown): resolve relative images for local sources - #4816

Merged
dolfim-ibm merged 1 commit into
docling-project:mainfrom
hktitof:fix/markdown-local-relative-images
Oct 14, 2026
Merged

dolfim-ibm merged 1 commit into
docling-project:mainfrom
hktitof:fix/markdown-local-relative-images

Conversation

@hktitof

@hktitof hktitof commented Oct 14, 2026

Copy link
Copy Markdown
Contributor

Context: Sibling to #4697 (which fixed the same missing source_uri fill-in for a LaTeX str source). This addresses MarkdownFormatOption.backend_options_for_input at docling/document_converter.py line 199, which still has no override, so a local markdown file cannot load its own relative images.

this fixes relative images not loading when you convert a local markdown file

i hit this while converting a local .md file that points at an image with a relative path

what is wrong

MarkdownBackendOptions has a source_uri field and the markdown backend uses it as the base path to resolve relative image paths, but MarkdownFormatOption never fills it in from the input source

so when you convert a local markdown file with fetch_images and enable_local_fetch on, the image is never loaded and you get this warning

UserWarning: Could not process an image from img.png: Local file access requires base_path for directory confinement: 'img.png'

the other backends that use source_uri already fill it in, HTMLFormatOption and AsciiDocFormatOption have a backend_options_for_input override, and LatexFormatOption got one in #4697 for the same kind of problem

markdown was the one left out

steps to reproduce

  1. put an image and a markdown file that references it with a relative path in the same folder
  2. convert the markdown file with a converter built from MarkdownFormatOption and MarkdownBackendOptions(fetch_images=True, enable_local_fetch=True)
  3. the picture item stays empty

raw output on master before the change, for both a str path and a Path

MD    hook(str)  source_uri = None
MD    hook(Path) source_uri = None
convert(str) status=ConversionStatus.SUCCESS pictures/loaded = (1, 0)
convert(Path) status=ConversionStatus.SUCCESS pictures/loaded = (1, 0)
UserWarning: Could not process an image from img.png: Local file access requires base_path for directory confinement: 'img.png'

the fix

add the same backend_options_for_input override to MarkdownFormatOption that HTMLFormatOption and AsciiDocFormatOption already have, so source_uri is filled from a local str or Path source

after the change

MD    hook(str)  source_uri = PurePosixPath('/tmp/.../doc.md')
MD    hook(Path) source_uri = PosixPath('/tmp/.../doc.md')
convert(str) status=ConversionStatus.SUCCESS pictures/loaded = (1, 1)
convert(Path) status=ConversionStatus.SUCCESS pictures/loaded = (1, 1)

if you set source_uri yourself it still wins, backend_options=None still returns None, and a DocumentStream is left alone, same as the HTML and AsciiDoc versions

tests

added one parametrized test in tests/test_backend_markdown.py that covers both str and Path input, it fails on master and passes with the fix

i also ran

  • tests/test_backend_markdown.py tests/test_backend_asciidoc.py tests/test_backend_text_encoding.py -> 112 passed
  • ruff check on both changed files -> clean
  • ruff format --check on both changed files -> clean

note: there are open PRs that touch document_converter.py and tests/test_backend_markdown.py, i checked them and none fixes this same defect, so the file overlap is just a rebase cost if it happens

all of this is cpu only on a local sandbox, no gpu and no model weights involved

Checklist

  • Documentation has been updated, if necessary.
  • Examples have been added, if necessary.
  • Tests have been added, if necessary.

Review evidence

Before: on main, convert("doc.md") with fetch_images=True, enable_local_fetch=True gives pictures/loaded = (1, 0) and logs the base_path warning, the picture item has no image.

After: the same call gives pictures/loaded = (1, 1) for both a str and a Path source, and the loaded image keeps its original 7x5 pixels.

Checks performed:

  • pytest tests/test_backend_markdown.py -> 36 passed
  • pytest tests/test_backend_markdown.py tests/test_backend_asciidoc.py tests/test_backend_text_encoding.py -> 112 passed
  • the new test re-run with the override reverted on main -> 2 failed (assert None is not None), so it fails without the change
  • python3 scripts/check_max_lines.py --max-lines=1500 on both files -> pass
  • git diff --check -> pass

MarkdownBackendOptions.source_uri resolves relative image paths, but
MarkdownFormatOption did not fill it in from the input source, so a
local Markdown file converted with fetch_images=True could not load
its own relative images. The other backends that use source_uri, HTML,
AsciiDoc, and LaTeX since docling-project#4697, fill it in from the input.

Add the backend_options_for_input override to MarkdownFormatOption, the
same way HTMLFormatOption and AsciiDocFormatOption already do it.

Signed-off-by: Abdel <62770500+hktitof@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown
Contributor

✅ DCO Check Passed

Thanks @hktitof, all your commits are properly signed off. 🎉

@mergify

mergify Bot commented Oct 14, 2026

Copy link
Copy Markdown
Contributor

Merge Protections

🟢 Merge protection satisfied — ready to merge.

Show 1 satisfied protection

🟢 Enforce conventional commit

Make sure that we follow https://www.conventionalcommits.org/en/v1.0.0/

  • title ~= ^(fix|feat|docs|style|refactor|perf|test|build|ci|chore|revert)(?:\(.+\))?(!)?:

@github-actions github-actions Bot added ai:ci-safe AI triage found no CI-safety concern (advisory) bug Something isn't working markdown issue related to markdown backend labels Oct 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

AI triage (advisory)

Checked commit f9db1ccc6f. The analysis read the diff only. It did not run code from this pull request.

This pull request sets backend options for local Markdown inputs to include the source URI. This allows the Markdown backend to resolve relative image paths.

Topic labels added: bug, markdown.

CI safety: no concern found. A maintainer must still approve CI.

1 related pull request(s) in the same code
PR State Signal Assessment
#4697 merged referenced as #4697 related: PR #4697 added backend options handling for LaTeX sources, while this pull request adds backend options handling for Markdown sources.

The ai:* labels are advisory. They do not approve CI and they do not add tests:full. A new push runs this check again.

@github-actions github-actions Bot added the ai:review-lgtm AI first review found no blocker or major issue (advisory) label Oct 14, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI first review (advisory): no blocker found

This review covers the full diff at f9db1ccc6f. It read the code and did not run it.

The fix correctly mirrors the existing AsciiDocFormatOption.backend_options_for_input pattern and the test covers both str and Path sources. Verify that the model_validate coercion of a local str path to PurePath works as expected, since AsciiDocFormatOption uses the same implicit coercion while LatexFormatOption explicitly converts to Path(source). No blocker found.

A maintainer makes the merge decision. This review never approves the pull request.

@codecov

codecov Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@dolfim-ibm dolfim-ibm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@dolfim-ibm
dolfim-ibm merged commit 8119cdc into docling-project:main Oct 14, 2026
33 checks passed
@hktitof

hktitof commented Oct 14, 2026

Copy link
Copy Markdown
Contributor Author

thanks for the review and merge @dolfim-ibm, happy to contribute to docling!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai:ci-safe AI triage found no CI-safety concern (advisory) ai:review-lgtm AI first review found no blocker or major issue (advisory) bug Something isn't working markdown issue related to markdown backend

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants