didi/DoKit · error · IllegalStateException

Already in chunked mode

Error message

Already in chunked mode

What it means

setFixedLengthStreamingMode(long) refuses to run when chunked streaming mode is already enabled (chunkLength > 0), throwing IllegalStateException("Already in chunked mode"). A request body can use exactly one transfer strategy: fixed-length or chunked, not both.

Source

Thrown at Android/dokit/src/main/java/com/didichuxing/doraemonkit/aop/urlconnection/ObsoleteUrlFactory.java:738

        }

        @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;
                this.handshake = response.handshake();

View on GitHub (pinned to 626827cddb)

Solutions

  1. Pick one streaming mode per connection; remove the conflicting setChunkedStreamingMode call.
  2. If both code paths must coexist, guard with a flag so only the first mode call wins.
  3. Prefer fixed-length when the body size is known; use chunked only when it is not.

Example fix

// before
conn.setChunkedStreamingMode(0);
conn.setFixedLengthStreamingMode(body.length); // ISE

// after
conn.setFixedLengthStreamingMode(body.length); // only one mode
Defensive patterns

Strategy: validation

Validate before calling

boolean streamingModeSet = false;
void setStreaming(HttpURLConnection c, long len) {
  if (streamingModeSet) return; // first mode wins
  if (len >= 0) c.setFixedLengthStreamingMode(len); else c.setChunkedStreamingMode(0);
  streamingModeSet = true;
}

Prevention

When it happens

Trigger: Calling setChunkedStreamingMode(...) and then setFixedLengthStreamingMode(...) on the same connection — commonly when one layer (e.g. a cookie/auth wrapper or library default) enables chunked while app code sets fixed length.

Common situations: Framework code defaulting to chunked uploads while the app sets an exact content length; merging two upload implementations that each pick a streaming mode.

Related errors


AI-assisted analysis of didi/DoKit@626827cddb (2026-08-14). Data as JSON: /api/errors/2bfa641180536e8f. Report an issue: GitHub.