Skip to content

fix(windows): give blocks a media path without the verbatim prefix - #1045

Merged
srperens merged 2 commits into
mainfrom
fix/windows-verbatim-media-path
Oct 8, 2026
Merged

srperens merged 2 commits into
mainfrom
fix/windows-verbatim-media-path

Conversation

@srperens

@srperens srperens commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

Closes #835

Problem

On Windows no Recorder flow writes a file. block_expansion canonicalizes media_path for every block, and on Windows canonicalize() returns a verbatim path (\\?\C:\...). The Recorder joins its file name onto that with /. Inside a verbatim path / is not a separator, so filesink refuses the location, splitmuxsink stays in READY, and the flow never reaches EOS. Root cause found by @wagenet in #835; from his diagnostic run on the Windows runner:

GstFileSink:sink: Could not open file "\\?\C:\Users\runneradmin\AppData\Local\Temp\.tmp52YXSk\recordings/diag_20261005_155721_00000.mp4" for writing.
gstfilesink.c(509): gst_file_sink_open_file (): system error: Invalid argument

Every flow goes through block_expansion, so this hits a real Windows server, not only the test.

Change

  • block_expansion canonicalizes with dunce::canonicalize instead of Path::canonicalize. dunce returns the plain C:\... form whenever that form is valid, and keeps the verbatim form only where it is needed. On Linux and macOS it is std::fs::canonicalize, so nothing changes there. dunce was already in Cargo.lock as a transitive dependency.
  • recorder_records_when_driven_through_pipeline_start is no longer ignored on Windows.

Rejected:

  • Building the Recorder's location with Path::join instead of /. That fixes one block; every block that joins onto _media_path with / would still break. The Live Recorder in feat(live recorder): a recorder where a quiet track holds nothing up #1034 builds its location the same way (format!("{}/{}_{}_%05d.{}", ...)) and would hit this too.
  • std::path::absolute instead of canonicalizing. It drops symlink resolution, which other code may rely on.

Evidence

  • The test fails on Windows without the fix. Commit 1 (86921c9) only removes the ignore; Build (Windows) in run 37754917806:
    test unfed_track::recorder_records_when_driven_through_pipeline_start ... FAILED
    pipeline reached EOS within 30s — a splitmuxsink pad for a connected track was not requested in time: Elapsed(())
    
  • The test passes on Windows with the fix. Commit 2 (5fb89ae), Build (Windows) in run 37757051131:
    test unfed_track::recorder_records_when_driven_through_pipeline_start ... ok
    

Tests

  • Ran: pre-commit hook (cargo fmt --check, cargo clippy --workspace --all-targets --features efp,nvidia -D warnings), macOS.
  • Windows CI (ci:windows) on both commits: see Evidence. Build (Windows) is still red on commit 2 for one unrelated test, media_download_test::partial_download_never_appears_under_the_final_name ("the first half never reached the disk"). It fails the same way on main (run 37751779361, after feat(media): download a file from a URL, and stream uploads with progress #1043), so it is not caused by this PR.
  • port_pool_test::a_port_held_by_another_process_is_skipped_and_marked_blocked failed on commit 1 and passed on commit 2; it also failed on main in run 37751779361. Unrelated to this change.

For the reviewer

  • Every block now gets _media_path without the \\?\ prefix on Windows. The Media Player canonicalizes its own paths again (mediaplayer/mod.rs) and is not affected by this change.

Out of scope

🤖 Generated with Claude Code

It was ignored on Windows because the flow never reached EOS (#835).
This commit only removes the ignore, so Windows CI shows the failure
before the fix in the next commit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@srperens srperens added the ci:windows Run Build (Windows) on this pull request label Oct 8, 2026
block_expansion canonicalized media_path with Path::canonicalize, which
returns a verbatim \\?\C:\... path on Windows. Blocks join file names
onto it with '/', which is not a separator inside a verbatim path, so
filesink refused the Recorder's location and the flow never reached EOS.

dunce::canonicalize returns the plain C:\... form whenever it is valid.
On Linux and macOS it is std::fs::canonicalize.

Closes #835

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@srperens
srperens marked this pull request as ready for review October 8, 2026 09:46
@srperens
srperens merged commit 5f030c3 into main Oct 8, 2026
7 of 9 checks passed
@srperens
srperens deleted the fix/windows-verbatim-media-path branch October 8, 2026 09:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:windows Run Build (Windows) on this pull request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Windows: a recorder flow never reaches EOS, so splitmuxsink never finalizes the file

1 participant