Fix PermissionError on Windows when building durable functions emulator image#8807
Merged
roger-zhangg merged 9 commits intodevelopfrom Mar 17, 2026
Merged
Fix PermissionError on Windows when building durable functions emulator image#8807roger-zhangg merged 9 commits intodevelopfrom
roger-zhangg merged 9 commits intodevelopfrom
Conversation
Use to_posix_path() to convert the emulator data directory path from Windows-style (D:\a\...) to POSIX-style (/d/a/...) before passing it as a Docker volume mount key. Docker inside WSL2 cannot parse Windows paths in volume specifications.
…st volume paths - Remove emoji characters from CLI output in durable_formatters.py and durable_callback_handler.py. Windows charmap codec cannot encode Unicode emojis, causing 'charmap codec can't encode character' errors. - Normalize CRLF to LF in integration test stderr comparisons for test_execution.py and test_callback.py (Windows outputs \r\n). - Update unit test volume path assertion to use to_posix_path() matching the source code change. - Update all unit tests referencing the removed emoji strings.
Use encoding='utf-8' in start_command_with_streaming Popen call. On Windows, text=True defaults to cp1252, which silently kills the output reader thread if any non-cp1252 bytes appear, causing wait_for_callback_id to time out.
Restore all emoji characters in durable CLI output. Instead of removing them, set PYTHONUTF8=1 in the integration-tests.yml workflow env to force Python to use UTF-8 on Windows. This makes click.echo handle emoji correctly without changing the user-facing output.
bchampp
approved these changes
Mar 17, 2026
valerena
approved these changes
Mar 17, 2026
valerena
approved these changes
Mar 17, 2026
|
|
||
| volumes = { | ||
| emulator_data_dir: {"bind": "/tmp/.durable-executions-local", "mode": "rw"}, | ||
| to_posix_path(emulator_data_dir): {"bind": "/tmp/.durable-executions-local", "mode": "rw"}, |
Contributor
There was a problem hiding this comment.
Not an issue, but something I found and I leave it here in case it helps someone else.
This to_posix_path is done inside our Container class
aws-sam-cli/samcli/local/docker/container.py
Lines 244 to 245 in 7c807bf
self._docker_client.containers.create directly, without passing through the Container implementation, so it needs to do this again.
vicheey
approved these changes
Mar 17, 2026
| LOG.info("Sending first callback: %s", " ".join(succeed_command)) | ||
| result = run_command(succeed_command) | ||
| self.assertEqual(result.process.returncode, 0) | ||
| stdout_str = result.stdout.decode("utf-8") if isinstance(result.stdout, bytes) else result.stdout |
Contributor
There was a problem hiding this comment.
Nit: we should have a util function for this check and conversion. Not a blocker but for clarity.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Durable function integration tests (
test_tier1_callback,test_tier1_execution,test_tier1_durable_invoke) fail on Windows (WSL2) runners with three distinct issues:PermissionError: [Errno 13] Permission denied: 'D:\\a\\_temp\\...Dockerfile'invalid volume specification: 'D:\a\aws-sam-cli\...''charmap' codec can't encode character '\u2705'and\r\nvs\nassertion mismatchesAll tests pass on Linux.
Failed integ test: https://github.com/aws/aws-sam-cli/actions/runs/23079727144/job/67046559248
Root Causes
1. NamedTemporaryFile file locking (PermissionError)
In
_build_emulator_image(),NamedTemporaryFilewith defaultdelete=Trueholds an exclusive lock on the file while thewithblock is active. Whentarfile.add()tries to read the same file, Windows enforces mandatory file locking and raisesPermissionError. Linux doesn't enforce mandatory locks, so it works there.2. Windows path in Docker volume mount
_get_emulator_data_dir()returns a Windows-style path (D:\a\aws-sam-cli\...), which is passed directly as a Docker volume mount key. Docker inside WSL2 cannot parse Windows paths. SAM CLI already hasto_posix_path()for this exact conversion (D:\a\...→/d/a/...), but it wasn't being used here.3. Emoji encoding + CRLF line endings
CLI output uses Unicode emoji characters (✅❌💓🛑⚠️ 🔄) that Windows' default
charmapcodec cannot encode, causingclick.echo()to crash when running the test in github windows runner. Additionally, Windows outputs\r\nline endings in stderr, but tests compare against\n.Fix
NamedTemporaryFile
Use
delete=False, close the file beforetarfile.add()reads it, and manually clean up withos.unlink()in afinallyblock.Volume mount path
Apply
to_posix_path()to the emulator data directory before using it as a Docker volume key. This is a no-op on Linux/macOS (os.name != 'nt'), and on Windows it produces the/d/...format that both Docker Desktop and WSL2 Docker understand.Emoji + CRLF
Set utf-8 as default encoding when running the integration tests.. Add
\r\n→\nnormalization in integration test stderr comparisons.Testing