D4Vinci/Scrapling · error · ValueError

Unknown file type: filename must end with '.md', '.html', or

Error message

Unknown file type: filename must end with '.md', '.html', or '.txt'

What it means

write_content_to_file dispatches on the filename's extension: only '.md', '.html', and '.txt' are mapped (to markdown, html, and text extraction respectively via _extension_map). Any other extension (or no extension) raises ValueError listing the allowed set, because there would be no extraction strategy to apply.

Source

Thrown at scrapling/core/shell.py:667

                            "\t",
                            " ",
                        ):
                            # Remove consecutive white-spaces
                            txt_content = TextHandler(re_sub(f"[{s}]+", s, txt_content))
                        yield txt_content
            yield ""

    @classmethod
    def write_content_to_file(
        cls, page: Selector, filename: str, css_selector: Optional[str] = None, main_content_only: bool = False
    ) -> None:
        """Write a Selector's content to a file"""
        if not page or not isinstance(page, Selector):  # pragma: no cover
            raise TypeError("Input must be of type `Selector`")
        elif not filename or not isinstance(filename, str) or not filename.strip():
            raise ValueError("Filename must be provided")
        elif not filename.endswith((".md", ".html", ".txt")):
            raise ValueError("Unknown file type: filename must end with '.md', '.html', or '.txt'")
        else:
            with open(filename, "w", encoding=page.encoding) as f:
                extension = filename.split(".")[-1]
                f.write(
                    "".join(
                        cls._extract_content(
                            page,
                            cls._extension_map[extension],
                            css_selector=css_selector,
                            main_content_only=main_content_only,
                        )
                    )
                )

View on GitHub (pinned to 5d213a2d47)

Solutions

  1. Use one of the three exact extensions: .md, .html, .txt
  2. Normalize case: filename = filename.lower() before the call if sources may use .MD/.HTML
  3. If you need another format, write to .html/.md/.txt and convert with a dedicated tool afterwards

Example fix

# before
Convertor.write_content_to_file(page, 'report.PDF')

# after
Convertor.write_content_to_file(page, 'report.md')
Defensive patterns

Strategy: validation

Validate before calling

EXTS = ('.md', '.html', '.txt')
filename = filename.lower()
if not filename.endswith(EXTS):
    filename += '.md'  # or reject explicitly

Type guard

from typing import Any

def has_supported_ext(filename: Any) -> bool:
    return isinstance(filename, str) and filename.lower().endswith(('.md', '.html', '.txt'))

Prevention

When it happens

Trigger: Calling write_content_to_file(page, 'out.docx'), 'page.json', 'archive.tar.gz', or 'output' (no extension). The check is on the literal suffix, so '.Markdown' or '.MD' (case-sensitive) also fail.

Common situations: Generating filenames from content type or site names (e.g. '.pdf' assumed supported), uppercase extensions from Windows-origin paths, or extension stripped by path handling.

Related errors


AI-assisted analysis of D4Vinci/Scrapling@5d213a2d47 (2026-08-14). Data as JSON: /api/errors/bfd59c9aa818b64d. Report an issue: GitHub.