Gateway support for .stl/.3mf and other attachment types
Cluster 53249 · gateway. Data as of
Nothing open on GitHub. Fix merged in #65510 on 16 Jul 2026. Check it covers your case.
The short answer
- Known?
- Yes. 4 related items grouped here, 1 issue already closed.
- Fix event
- A fix was merged to main in PR #65510. Check it covers your case. No release data is tracked.
- Tracker
- The maintainers' tracker marks this
unresolved. That is separate from the fix event. - Still open
- Nothing open on GitHub.
These items concern the gateway's handling of file attachments, mainly .stl and .3mf uploads (one reports Telegram rejecting them), with related changes touching .py/.markdown types and MEDIA: tag delivery through validated egress. The members appear to share a theme of expanding or fixing accepted attachment file types, though their exact scopes differ.
Open issues0
Open PRs0
Fixes on record
-
#65510 fix(gateway): deliver MEDIA: tags for every file type via validated egress
files:
gateway/platforms/base.py,tests/gateway/test_platform_base.pyShow the diff
-
gateway/platforms/base.py@@ -1504,12 +1504,16 @@ def _log_safe_path(path: str) -> str: re.IGNORECASE, ) -# Extension-less absolute paths (e.g. Caddyfile, Dockerfile, Makefile) are -# intentionally excluded from MEDIA_TAG_CLEANUP_RE — they are validated and -# delivered via MEDIA_EXTENSIONLESS_TAG_RE so prompt-injection paths that do -# not exist on disk are left visible instead of silently dropped. Paths with -# an unknown but present extension (e.g. .weirdext) stay on the #34517 -# bare-path fallback and are not handled here. +# Paths NOT covered by MEDIA_TAG_CLEANUP_RE's extension alternation — both +# extension-less files (Caddyfile, Dockerfile, Makefile) and files with an +# unknown extension (.py, .log, .weirdext, ...) — are validated and delivered +# via MEDIA_EXTENSIONLESS_TAG_RE. Every ``MEDIA:`` path is therefore +# deliverable regardless of file type (#36060): known extensions extract +# unconditionally via the anchored pattern above, everything else extracts +# only after ``validate_media_delivery_path`` accepts it (exists on disk, not +# under the credential/system denylist, strict-mode rules honored), so +# prompt-injection paths that do not validate are left visible instead of +# silently dropped. MEDIA_EXTENSIONLESS_TAG_RE = re.compile( r'''[`"']?MEDIA:\s*''' r'''(?P<path>`[^`\n]+`|"[^"\n]+"|'[^'\n]+'|''' @@ -1527,8 +1531,16 @@ def _normalize_media_tag_path(raw: str) -> str: def _path_lacks_deliverable_extension(path: str) -> bool: - """True only when the basename has no extension (Caddyfile, Makefile, …).""" - return not Path(path).suffix + """True when MEDIA_TAG_CLEANUP_RE's extension alternation does not cover + ``path`` — either the basename has no extension at all (Caddyfile, + Makefile, …) or the extension is not in MEDIA_DELIVERY_EXTS (.py, .log, + .weirdext, …). Such paths route through the validated delivery pass + (``validate_media_delivery_path``) instead of the unconditional one, so + every file type is deliverable (#36060) while nonexistent / denylisted + paths stay visible in the text. + """ + suffix = Path(path).suffix.lower() + return not suffix or suffix not in MEDIA_DELIVERY_EXTS def _strip_media_tag_directives(text: str) -> str: -
tests/gateway/test_platform_base.py@@ -631,12 +631,15 @@ def test_extract_media_and_local_files_share_one_extension_set(self): def test_unknown_extension_not_black_holed_by_cleanup(self): """A MEDIA: tag with an unknown extension is NOT stripped from the - body — it survives so extract_local_files can still see the bare path, - rather than vanishing entirely (the core of issue #34517).""" + body by the extension-anchored cleanup — and when the path does not + validate (nonexistent file here), it is not delivered either, so the + tag survives visibly instead of vanishing (the core of issue #34517). + Validated unknown-extension paths DO deliver — see + TestUniversalMediaEgress (#36060).""" from gateway.platforms.base import MEDIA_TAG_CLEANUP_RE text = "Saved to MEDIA:/tmp/data.weirdext done" media, _ = BasePlatformAdapter.extract_media(text) - assert media == [] # unknown extension is not a deliverable MEDIA tag + assert media == [] # nonexistent path fails validation, not delivered stripped = MEDIA_TAG_CLEANUP_RE.sub("", text) assert "/tmp/data.weirdext" in stripped # path preserved, not dropped @@ -712,6 +715,104 @@ def test_as_document_directive_stripped_without_media_tag(self): ) +class TestUniversalMediaEgress: + """#36060: every MEDIA: path is deliverable regardless of file type. + + Known extensions extract unconditionally (MEDIA_TAG_CLEANUP_RE); unknown + extensions and extension-less files extract via the validated pass — + delivered when validate_media_delivery_path accepts them, left visible + when it does not (nonexistent, denylisted). + """ + + def _patch_allow_root(self, monkeypatch, root): + monkeypatch.setattr( + "gateway.platforms.base.MEDIA_DELIVERY_SAFE_ROOTS", + (str(root),), + ) + monkeypatch.delenv("HERMES_MEDIA_DELIVERY_STRICT", raising=False) + + @pytest.mark.parametrize("name", [ + "script.py", "server.log", "notes.weirdext", "app.ts", "run.sh", + "config.toml", "styles.css", "contract.sol", + ]) + def test_unknown_extension_delivered_when_file_validates( + self, tmp_path, monkeypatch, name, + ): + root = tmp_path / "output" + root.mkdir() + f = root / name + f.write_text("content", encoding="utf-8") + self._patch_allow_root(monkeypatch, root) + + content = f"Here you go:\nMEDIA:{f}\nDone." + media, cleaned = BasePlatformAdapter.extract_media(content) + assert len(media) == 1 + assert media[0][0] == str(f.resolve()) + assert "MEDIA:" not in cleaned + assert "Done." in cleaned + + def test_unknown_extension_left_visible_when_not_on_disk( + self, tmp_path, monkeypatch, + ): + root = tmp_path / "output" + root.mkdir() + self._patch_allow_root(monkeypatch, root) + + content = "MEDIA:/nonexistent/script.py" + media, cleaned = BasePlatformAdapter.extract_media(content) + assert media == [] + assert "MEDIA:/nonexistent/script.py" in cleaned + + def test_denylisted_paths_still_rejected_regardless_of_extension( + self, tmp_path, monkeypatch, + ): + # A denylisted path must not deliver even though .py/.log/etc now + # route through the validated pass. _media_delivery_denied_paths() + # reads _MEDIA_DELIVERY_DENIED_PREFIXES at call time, so patching the + # tuple exercises the real denylist logic. + secret_dir = [redacted:secret-assignment] / "secrets" + secret_dir.mkdir() + f = secret_dir / "creds.py" + f.write_text("TOKEN = 'x'", encoding="utf-8") + monkeypatch.setattr( + "gateway.platforms.base._MEDIA_DELIVERY_DENIED_PREFIXES", + (str(secret_dir),), + ) + monkeypatch.delenv("HERMES_MEDIA_DELIVERY_STRICT", raising=False) + + content = f"MEDIA:{f}" + media, cleaned = BasePlatformAdapter.extract_media(content) + assert media == [] + assert "MEDIA:" in cleaned # rejected tag stays visible + + def test_strip_for_display_strips_validated_unknown_extension( + self, tmp_path, monkeypatch, + ): + root = tmp_path / "output" + root.mkdir() + f = root / "server.log" + f.write_text("x", encoding="utf-8") + self._patch_allow_root(monkeypatch, root) + + text = f"MEDIA:{f}" + stripped = BasePlatformAdapter.strip_media_directives_for_display(text) + assert "MEDIA:" not in stripped + + def test_strip_for_display_keeps_unvalidated_unknown_extension(self): + text = "MEDIA:/nonexistent/server.log" + stripped = BasePlatformAdapter.strip_media_directives_for_display(text) + assert "MEDIA:/nonexistent/server.log" in stripped + + def test_known_extension_still_unconditional(self): + # Known extensions keep the pre-#36060 behavior: extracted (and the + # tag stripped) even when the file does not exist — downstream + # delivery surfaces the failure. + content = "MEDIA:/nonexistent/report.pdf" + media, cleaned = BasePlatformAdapter.extract_media(content) + assert media == [("/nonexistent/report.pdf", False)] + assert "MEDIA:" not in cleaned + + class TestMediaDeliveryPathValidation: def _patch_roots(self, monkeypatch, *roots): monkeypatch.setattr(
-
2 PRs closed without merging
From the close comments: done elsewhere 2
Closed issues · 1
- Closed#53249Telegram gateway rejects .stl / .3mf attachments — silently breaks 3D-printing agent workflows
How this cluster was grouped
-
Link evidence (
structural links throughout): every member is connected by structural evidence: shared changed files, or a closing/superseded reference. -
Pairwise link density
0.50: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36.1.00means every pair is linked.
Pick up a Lab task
Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.
Open the LabAt a glance
- Subsystem
- gateway
- Merged PRs
- #65510
- Closed issues
- 1
- Attempts
- 2 PRs closed without merging
- Fix link checked
- 16 Jul 2026