{"record":{"id":"0d1bded6ed733019","repo":"github/copilot-sdk","slug":"failed-to-write-a-frame-to-the-in-process-runtime-0d1bde","errorCode":null,"errorMessage":"Failed to write a frame to the in-process runtime connection.","messagePattern":"Failed to write a frame to the in-process runtime connection\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"dotnet/src/FfiRuntimeHost.cs","lineNumber":630,"sourceCode":"        public override long Length => throw new NotSupportedException();\n        public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); }\n        public override void Flush() { }\n        public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException();\n        public override void SetLength(long value) => throw new NotSupportedException();\n        public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException();\n    }\n\n    /// <summary>\n    /// A write-only stream that forwards each frame to the native\n    /// <c>connection_write</c> export.\n    /// </summary>\n    private sealed class CallbackSendStream(FrameWriter write) : Stream\n    {\n        private void WriteFrame(ReadOnlySpan<byte> frame)\n        {\n            if (!write(frame))\n            {\n                throw new IOException(\"Failed to write a frame to the in-process runtime connection.\");\n            }\n        }\n\n        public override void Write(byte[] buffer, int offset, int count) => WriteFrame(buffer.AsSpan(offset, count));\n\n#if !NETSTANDARD2_0\n        public override void Write(ReadOnlySpan<byte> buffer) => WriteFrame(buffer);\n\n        public override ValueTask WriteAsync(ReadOnlyMemory<byte> buffer, CancellationToken cancellationToken = default)\n        {\n            WriteFrame(buffer.Span);\n            return ValueTask.CompletedTask;\n        }\n#endif\n\n        public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)\n        {\n            WriteFrame(buffer.AsSpan(offset, count));","sourceCodeStart":612,"sourceCodeEnd":648,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/dotnet/src/FfiRuntimeHost.cs#L612-L648","documentation":"CallbackSendStream.WriteFrame throws IOException when the frame-write callback (backed by copilot_runtime_connection_write) returns false, i.e. the native runtime refused or failed to accept the outgoing JSON-RPC frame on the in-process connection.","triggerScenarios":"Sending a request/notification while the native connection is closed or broken; the runtime returning failure from its write callback (peer shut down, host already stopped, internal buffer error).","commonSituations":"Writing after the runtime crashed or was shut down; racing a StartAsync failure with pending sends; native host exited mid-session (e.g. killed process, failed connection open on the native side).","solutions":["Check whether the FfiRuntimeHost/connection is still open before sending; stop and reconnect if not.","Restart the runtime connection (new host via Create + StartAsync) after the write failure.","Inspect native logs for the reason the write callback reported failure.","Add an orderly Shutdown before process exit to avoid writes into a torn-down connection.","Guard send paths so writes after a failed StartAsync are not attempted."],"exampleFix":"// before\nawait stream.WriteAsync(frame, token); // throws IOException if connection died\n// after\nif (!host.IsConnectionOpen) { await host.RestartAsync(token); }\nawait stream.WriteAsync(frame, token);","handlingStrategy":"try-catch","validationCode":"if (!connection.IsOpen) { await ReconnectAsync(ct); } // before every write batch","typeGuard":"bool CanSend(FfiRuntimeHost h) => h is { IsDisposed: false } && h.IsConnectionOpen;","tryCatchPattern":"try { await sendStream.WriteAsync(frame, ct); }\ncatch (IOException ex) when (ex.Message.Contains(\"Failed to write a frame\")) {\n    logger.LogWarning(ex, \"Runtime connection write failed; reopening\");\n    await ReconnectAsync(ct);\n}","preventionTips":["Check connection state before sending","Perform orderly Shutdown before process exit","Don't queue sends after a failed StartAsync","Monitor native host liveness and reconnect on failure"],"tags":["ffi","io","connection","broken-pipe"],"backgroundTag":"broken-pipe","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}