microsoft/aspire · error · OSError

WriteFile failed with error

Error message

WriteFile failed with error {error}

What it means

Raised by the Windows named-pipe socket wrapper when the WriteFile Win32 call fails with an unexpected error during overlapped I/O. This typically means the pipe's server end is gone (broken pipe) or the handle is invalid, so the write could not be delivered.

Solutions

  1. Catch OSError around sendall and reconnect before retrying the request.
  2. Verify the host is running when writes start failing (host exit is the usual cause).
  3. Ensure close() is not called concurrently with write operations.
  4. Decode the reported error code to distinguish broken pipe from disk/full or access issues.

Example fix

// before
socket.sendall(payload)

// after
try:
    socket.sendall(payload)
except OSError:
    socket = reconnect_to_pipe(pipe_path, timeout_sec=30)
    socket.sendall(payload)
Defensive patterns

Strategy: try-catch

Try / catch

try:
    sock.sendall(payload)
except OSError:
    sock = reconnect_to_pipe(pipe_path, timeout_sec=30)
    sock.sendall(payload)

Prevention

When it happens

Trigger: Sending a request over the pipe after the host process exited; writing to an already-closed handle; partial-write loop encountering ERROR_BROKEN_PIPE or ERROR_NO_DATA.

Common situations: Long-running client whose host was restarted between calls; AppHost terminated by Ctrl+C while client mid-request; race between close() and an in-flight write.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/0ae52527037fb78b. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting.CodeGeneration.Python/PythonModuleBuilder.cs:401

                                self._handle,
                                chunk,
                                len(chunk),
                                ctypes.byref(bytes_written),
                                ctypes.byref(overlapped)
                            )

                            if not success:
                                error = ctypes.get_last_error()
                                if error == self.ERROR_IO_PENDING:
                                    # Wait for the operation to complete
                                    _kernel32.GetOverlappedResult(
                                        self._handle,
                                        ctypes.byref(overlapped),
                                        ctypes.byref(bytes_written),
                                        True  # wait
                                    )
                                else:
                                    raise OSError(f"WriteFile failed with error {error}")

                            offset += bytes_written.value
                    finally:
                        _kernel32.CloseHandle(overlapped.hEvent)

                def close(self) -> None:
                    '''Close the handle.'''
                    if self._handle is not None and self._handle != self.INVALID_HANDLE_VALUE:
                        _kernel32.CloseHandle(self._handle)
                        self._handle = None

            def _connect_pipe(socket_path: str, timeout_sec: float) -> _PipeSocket:
                '''Connect to a named pipe with timeout, retrying until available.'''
                pipe_path = f"\\\\.\\pipe\\{socket_path}"
                _logger.debug("Connecting to: %s", pipe_path)

                start_time = time.time()
                while (time.time() - start_time) < timeout_sec:

View on GitHub (pinned to 25830f84bd)