didi/DoKit · error · IllegalStateException
Already connected
Error message
Already connected
What it means
setFixedLengthStreamingMode(long) may only be configured before the connection is established; the wrapper checks super.connected and throws IllegalStateException("Already connected") otherwise. Streaming mode decides how the request body is transmitted (fixed-length, no in-memory buffering), so changing it mid-flight is illegal.
Source
Thrown at Android/dokit/src/main/java/com/didichuxing/doraemonkit/aop/urlconnection/ObsoleteUrlFactory.java:737
requestHeaders.add(field, value);
}
@Override
public void setRequestMethod(String method) throws ProtocolException {
if (!METHODS.contains(method)) {
throw new ProtocolException("Expected one of " + METHODS + " but was " + method);
}
this.method = method;
}
@Override
public void setFixedLengthStreamingMode(int contentLength) {
setFixedLengthStreamingMode((long) contentLength);
}
@Override
public void setFixedLengthStreamingMode(long contentLength) {
if (super.connected) throw new IllegalStateException("Already connected");
if (chunkLength > 0) throw new IllegalStateException("Already in chunked mode");
if (contentLength < 0) throw new IllegalArgumentException("contentLength < 0");
this.fixedContentLength = contentLength;
super.fixedContentLength = (int) Math.min(contentLength, Integer.MAX_VALUE);
}
@Override
public void onFailure(Call call, IOException e) {
synchronized (lock) {
this.callFailure = (e instanceof UnexpectedException) ? e.getCause() : e;
lock.notifyAll();
}
}
@Override
public void onResponse(Call call, Response response) {
synchronized (lock) {
this.response = response;View on GitHub (pinned to 626827cddb)
Solutions
- Call setFixedLengthStreamingMode(bodyBytes.length) immediately after openConnection(), before any other state-advancing call.
- Compute the exact body length up front (serialize to byte[] first if needed).
- If length is unknown, use setChunkedStreamingMode() — also set before connect.
Example fix
// before OutputStream os = conn.getOutputStream(); conn.setFixedLengthStreamingMode(body.length); // ISE // after conn.setFixedLengthStreamingMode(body.length); OutputStream os = conn.getOutputStream();
Defensive patterns
Strategy: validation
Validate before calling
// immediately after openConnection(): conn.setFixedLengthStreamingMode(bodyBytes.length);
Prevention
- Configure streaming mode right after openConnection(), before anything else.
- Serialize the body first so its length is known up front.
When it happens
Trigger: Calling setFixedLengthStreamingMode() after connect(), getOutputStream(), getInputStream(), or getResponseCode() has already run.
Common situations: Upload code that decides content length after opening the output stream; wrapping libraries (e.g. multipart upload helpers) that set streaming mode late.
Related errors
- Cannot access request header fields after connection is set
- cannot write request body after response has been read
- Cannot set request property after connection is made
- Cannot add request property after connection is made
- Already in chunked mode
AI-assisted analysis of didi/DoKit@626827cddb (2026-08-14).
Data as JSON: /api/errors/afd7c0ae4d4fe002.
Report an issue: GitHub.