{"record":{"id":"2bfa641180536e8f","repo":"didi/DoKit","slug":"already-in-chunked-mode","errorCode":null,"errorMessage":"Already in chunked mode","messagePattern":"Already in chunked mode","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"Android/dokit/src/main/java/com/didichuxing/doraemonkit/aop/urlconnection/ObsoleteUrlFactory.java","lineNumber":738,"sourceCode":"        }\n\n        @Override\n        public void setRequestMethod(String method) throws ProtocolException {\n            if (!METHODS.contains(method)) {\n                throw new ProtocolException(\"Expected one of \" + METHODS + \" but was \" + method);\n            }\n            this.method = method;\n        }\n\n        @Override\n        public void setFixedLengthStreamingMode(int contentLength) {\n            setFixedLengthStreamingMode((long) contentLength);\n        }\n\n        @Override\n        public void setFixedLengthStreamingMode(long contentLength) {\n            if (super.connected) throw new IllegalStateException(\"Already connected\");\n            if (chunkLength > 0) throw new IllegalStateException(\"Already in chunked mode\");\n            if (contentLength < 0) throw new IllegalArgumentException(\"contentLength < 0\");\n            this.fixedContentLength = contentLength;\n            super.fixedContentLength = (int) Math.min(contentLength, Integer.MAX_VALUE);\n        }\n\n        @Override\n        public void onFailure(Call call, IOException e) {\n            synchronized (lock) {\n                this.callFailure = (e instanceof UnexpectedException) ? e.getCause() : e;\n                lock.notifyAll();\n            }\n        }\n\n        @Override\n        public void onResponse(Call call, Response response) {\n            synchronized (lock) {\n                this.response = response;\n                this.handshake = response.handshake();","sourceCodeStart":720,"sourceCodeEnd":756,"githubUrl":"https://github.com/didi/DoKit/blob/626827cddb2feb2f3aee87a52a064b4e5ca2bed4/Android/dokit/src/main/java/com/didichuxing/doraemonkit/aop/urlconnection/ObsoleteUrlFactory.java#L720-L756","documentation":"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.","triggerScenarios":"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.","commonSituations":"Framework code defaulting to chunked uploads while the app sets an exact content length; merging two upload implementations that each pick a streaming mode.","solutions":["Pick one streaming mode per connection; remove the conflicting setChunkedStreamingMode call.","If both code paths must coexist, guard with a flag so only the first mode call wins.","Prefer fixed-length when the body size is known; use chunked only when it is not."],"exampleFix":"// before\nconn.setChunkedStreamingMode(0);\nconn.setFixedLengthStreamingMode(body.length); // ISE\n\n// after\nconn.setFixedLengthStreamingMode(body.length); // only one mode","handlingStrategy":"validation","validationCode":"boolean streamingModeSet = false;\nvoid setStreaming(HttpURLConnection c, long len) {\n  if (streamingModeSet) return; // first mode wins\n  if (len >= 0) c.setFixedLengthStreamingMode(len); else c.setChunkedStreamingMode(0);\n  streamingModeSet = true;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Choose one transfer mode per connection and centralize that choice in one method.","Audit wrappers/libraries that default to chunked before your code sets fixed length."],"tags":["network","http","urlconnection","streaming"],"backgroundTag":null,"analyzedSha":"626827cddb2feb2f3aee87a52a064b4e5ca2bed4","analyzedAt":"2026-08-14T12:45:58.758Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}