Files
VoiceStudio/tests/test_untrusted_mount_1957.py
T
Palash DebnathandClaude Opus 5 fd7d2d94dd fix(errors): explain a Windows untrusted-mount failure instead of echoing WinError 448
Closes #1957.

A download failed with nothing but the OS sentence: "[WinError 448] The path
cannot be traversed because it contains an untrusted mount point". That is a
Windows rule about the VOLUME — Dev Drives, mounted VHD/ReFS volumes and
junctions into another user profile all trigger it — so retrying the same link
can never work, and the message names nothing the user can change.

Classified now, with a remedy that points at Settings → Storage and gives the
fsutil escape hatch for a folder that has to stay put. Matched on the numeric
code first, since Windows translates the sentence, with the English phrase as a
fallback. Allowlisted for context-free surfaces because it arrives through the
global 500 handler, which otherwise attaches no hint at all — and its trigger
is unmistakable, so it cannot land on an unrelated failure.

A test pins that the offending path never comes back in the payload.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017ypcgSsh5j2PEonSJiAU1S
2026-09-09 13:47:51 -07:00

68 lines
2.5 KiB
Python

"""#1957 — WinError 448 must arrive with a remedy, not as a bare OS sentence.
A download failed with "[WinError 448] The path cannot be traversed because it
contains an untrusted mount point: <a folder on D:>" and nothing else.
That is a Windows rule about the VOLUME — Dev Drives, mounted VHD/ReFS volumes,
and junctions into another profile all trigger it — so no amount of retrying
the same link helps, and the message gives the user nothing to change.
Matched on the numeric code first because Windows translates the sentence, with
the English phrase as a fallback for locales that report it verbatim.
"""
import pytest
from core.failure import _CONTEXT_FREE_HINT_CLASSES, classify, public_hint_for_topic
from core.public_errors import public_exception_response
_RAW = (
"download: [WinError 448] The path cannot be traversed because it contains "
r"an untrusted mount point: 'D:\CodingStuff\nodejs'"
)
def test_the_windows_code_is_classified():
assert classify(_RAW) == "WINDOWS_UNTRUSTED_MOUNT"
def test_a_translated_message_still_classifies_on_the_code():
# Windows localises the sentence; the bracketed code is what survives.
assert classify("[WinError 448] Der Pfad kann nicht durchlaufen werden") == (
"WINDOWS_UNTRUSTED_MOUNT"
)
def test_the_english_phrase_alone_classifies():
assert classify("contains an untrusted mount point") == "WINDOWS_UNTRUSTED_MOUNT"
def test_the_hint_names_something_the_user_can_change():
hint = public_hint_for_topic("WINDOWS_UNTRUSTED_MOUNT")
assert "Storage" in hint
assert "448" in hint
def test_it_reaches_the_user_on_a_context_free_surface():
# The failure arrives through the global 500 handler, which only attaches
# hints from the allowlist — so being classified is not enough on its own.
assert "WINDOWS_UNTRUSTED_MOUNT" in _CONTEXT_FREE_HINT_CLASSES
payload = public_exception_response(OSError(_RAW), fallback="Internal error.")
assert payload["docs_topic"] == "WINDOWS_UNTRUSTED_MOUNT"
assert payload["detail"] != "Internal error."
def test_the_offending_path_is_never_echoed_back():
payload = public_exception_response(OSError(_RAW), fallback="Internal error.")
for value in payload.values():
assert "CodingStuff" not in str(value)
@pytest.mark.parametrize(
"other",
[
"[WinError 1260] blocked by an application control policy",
"[WinError 1455] The paging file is too small for this operation",
],
)
def test_the_other_windows_classes_are_untouched(other):
assert classify(other) != "WINDOWS_UNTRUSTED_MOUNT"