{"record":{"id":"afd7c0ae4d4fe002","repo":"didi/DoKit","slug":"already-connected","errorCode":null,"errorMessage":"Already connected","messagePattern":"Already connected","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"Android/dokit/src/main/java/com/didichuxing/doraemonkit/aop/urlconnection/ObsoleteUrlFactory.java","lineNumber":737,"sourceCode":"            requestHeaders.add(field, value);\n        }\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;","sourceCodeStart":719,"sourceCodeEnd":755,"githubUrl":"https://github.com/didi/DoKit/blob/626827cddb2feb2f3aee87a52a064b4e5ca2bed4/Android/dokit/src/main/java/com/didichuxing/doraemonkit/aop/urlconnection/ObsoleteUrlFactory.java#L719-L755","documentation":"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.","triggerScenarios":"Calling setFixedLengthStreamingMode() after connect(), getOutputStream(), getInputStream(), or getResponseCode() has already run.","commonSituations":"Upload code that decides content length after opening the output stream; wrapping libraries (e.g. multipart upload helpers) that set streaming mode late.","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."],"exampleFix":"// before\nOutputStream os = conn.getOutputStream();\nconn.setFixedLengthStreamingMode(body.length); // ISE\n\n// after\nconn.setFixedLengthStreamingMode(body.length);\nOutputStream os = conn.getOutputStream();","handlingStrategy":"validation","validationCode":"// immediately after openConnection():\nconn.setFixedLengthStreamingMode(bodyBytes.length);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Configure streaming mode right after openConnection(), before anything else.","Serialize the body first so its length is known up front."],"tags":["network","http","urlconnection","streaming","state-machine"],"backgroundTag":null,"analyzedSha":"626827cddb2feb2f3aee87a52a064b4e5ca2bed4","analyzedAt":"2026-08-14T12:45:58.758Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}