didi/DoKit · error · IllegalStateException

Cannot access request header fields after connection is set

Error message

Cannot access request header fields after connection is set

What it means

In OkHttpURLConnection, getRequestProperties() must return the request headers before the connection is established; the wrapper tracks a 'connected' flag (set true in buildCall()) and throws IllegalStateException if headers are read after that point. This matches HttpURLConnection's contract that request properties are inaccessible once connected.

Source

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

                return headers.name(position);
            } catch (IOException e) {
                return null;
            }
        }

        @Override
        public Map<String, List<String>> getHeaderFields() {
            try {
                return toMultimap(getHeaders(), statusLineToString(getResponse(true)));
            } catch (IOException e) {
                return Collections.emptyMap();
            }
        }

        @Override
        public Map<String, List<String>> getRequestProperties() {
            if (connected) {
                throw new IllegalStateException(
                        "Cannot access request header fields after connection is set");
            }

            return toMultimap(requestHeaders.build(), null);
        }

        @Override
        public InputStream getInputStream() throws IOException {
            if (!doInput) {
                throw new ProtocolException("This protocol does not support input");
            }

            Response response = getResponse(false);
            if (response.code() >= HTTP_BAD_REQUEST) {
                Log.e("DoKit", "FileNotFoundException:" + url.toString());
                return ConvertUtils.string2InputStream("FileNotFoundException:" + url.toString(), "utf-8");
            }

View on GitHub (pinned to 626827cddb)

Solutions

  1. Snapshot getRequestProperties() (or your own header map) before the first connect-triggering call.
  2. Move header logging to before getOutputStream()/getInputStream().
  3. For retries, keep the original headers in your own map instead of re-reading them from the connection.

Example fix

// before
conn.getOutputStream().write(body);
Map<String, List<String>> props = conn.getRequestProperties(); // ISE

// after
Map<String, List<String>> props = conn.getRequestProperties();
conn.getOutputStream().write(body);
Defensive patterns

Strategy: validation

Validate before calling

Map<String, List<String>> snapshot = new LinkedHashMap<>();
// fill snapshot as you set headers; read it after connect instead of conn.getRequestProperties()

Prevention

When it happens

Trigger: Calling getRequestProperties() after connect(), getOutputStream(), getInputStream(), getResponseCode(), or any other call that triggers buildCall()/getResponse().

Common situations: Logging or debugging code that dumps request headers after firing the request; retry wrappers that read request properties to rebuild a request after the first attempt already connected.

Related errors


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