kovidgoyal/kitty · error

Did not receive expected streaming response

Error message

Did not receive expected streaming response

What it means

simple_socket_io expected the peer's reply to look like a streaming response (validated by is_stream_response), but the bytes read from the connection did not match that format. This means the connection succeeded and data arrived, but the remote is not speaking the expected streaming protocol (e.g. it replied with a plain/error response instead).

Source

Thrown at tools/cmd/at/socket_io.go:151

			return
		}
		if len(chunk) == 0 {
			break
		}
		err = write_many_to_conn(conn, []byte(cmd_escape_code_prefix), chunk, []byte(cmd_escape_code_suffix))
		if err != nil {
			return
		}
		if !first_escape_code_sent {
			first_escape_code_sent = true
			if wants_streaming {
				var streaming_response []byte
				streaming_response, err = r.read_response_from_conn(conn, io_data.timeout)
				if err != nil {
					return
				}
				if !is_stream_response(streaming_response) {
					err = fmt.Errorf("Did not receive expected streaming response")
					return
				}
			}
		}
	}
	if io_data.rc.NoResponse {
		return
	}
	return r.read_response_from_conn(conn, io_data.timeout)
}

func do_socket_io(io_data *rc_io_data) (serialized_response []byte, err error) {
	var conn net.Conn
	if global_options.to_network == "fd" {
		fd, _ := strconv.Atoi(global_options.to_address)
		if err != nil {
			return nil, err
		}

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Verify the remote address/network actually serves the expected streaming protocol (test with the same tool version on both ends)
  2. Check that the peer process is the correct version and configured for streaming responses
  3. Capture the bytes returned (log streaming_response) to see what the peer actually sent — often an error message revealing the mismatch
  4. If a proxy sits in the path, bypass it or configure it to pass the stream through unmodified

Example fix

# before
at --to tcp:host:9000 --expect-stream
# after: point at the actual streaming endpoint and matching protocol version
at --to tcp:host:9001 --expect-stream  # port of the real streaming daemon
Defensive patterns

Strategy: validation

Validate before calling

// Before requesting streaming mode, probe the peer with a tiny request
// and confirm the reply matches the streaming protocol.
resp, err := probe(toAddr)
if err == nil && !isStreamResponse(resp) {
    log.Fatalf("peer at %s does not speak the streaming protocol; check address/version", toAddr)
}

Try / catch

// In Go: inspect the error text at the call site
if err != nil && strings.Contains(err.Error(), "Did not receive expected streaming response") {
    // peer reachable but wrong protocol: don't retry, alert on config
    log.Printf("protocol mismatch with %s — verify server version", addr)
    return err
}

Prevention

When it happens

Trigger: Calling the at tool with streaming mode requested (io_data requests a stream response) against a listener that answers with a non-streaming payload, closes early, or sends a protocol error frame, so is_stream_response(streaming_response) returns false after a successful read_response_from_conn.

Common situations: Pointing --to at the wrong port/service (e.g. an HTTP server instead of the expected streaming daemon), a version mismatch between client and server protocol, or a proxy that mangles/truncates the streamed reply.

Related errors


AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27). Data as JSON: /api/errors/157abbe201d1de78. Report an issue: GitHub.