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
- Snapshot getRequestProperties() (or your own header map) before the first connect-triggering call.
- Move header logging to before getOutputStream()/getInputStream().
- 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
- Maintain your own header map alongside the connection; never query the connection for request state after connect.
- Treat connect()/getOutputStream()/getInputStream() as point-of-no-return calls.
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
- 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 connected
- This protocol does not support input
AI-assisted analysis of didi/DoKit@626827cddb (2026-08-14).
Data as JSON: /api/errors/6593c5bc7350a0ac.
Report an issue: GitHub.