{"record":{"id":"5a3beed36f16fcf3","repo":"didi/DoKit","slug":"unexpected-header-line","errorCode":null,"errorMessage":"Unexpected header: \" + line","messagePattern":"Unexpected header: \" \\+ line","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/network/common/CommonHeaders.java","lineNumber":235,"sourceCode":"     */\n    Builder addLenient(String line) {\n      int index = line.indexOf(\":\", 1);\n      if (index != -1) {\n        return addLenient(line.substring(0, index), line.substring(index + 1));\n      } else if (line.startsWith(\":\")) {\n        // Work around empty header names and header names that start with a\n        // colon (created by old broken SPDY versions of the response cache).\n        return addLenient(\"\", line.substring(1)); // Empty header name.\n      } else {\n        return addLenient(\"\", line); // No header name.\n      }\n    }\n\n    /** Add an header line containing a field name, a literal colon, and a value. */\n    public Builder add(String line) {\n      int index = line.indexOf(\":\");\n      if (index == -1) {\n        throw new IllegalArgumentException(\"Unexpected header: \" + line);\n      }\n      return add(line.substring(0, index).trim(), line.substring(index + 1));\n    }\n\n    /** Add a field with the specified value. */\n    public Builder add(String name, String value) {\n      checkNameAndValue(name, value);\n      return addLenient(name, value);\n    }\n\n    /**\n     * Add a field with the specified value without any validation. Only appropriate for headers\n     * from the remote peer or cache.\n     */\n    Builder addLenient(String name, String value) {\n      namesAndValues.add(name);\n      namesAndValues.add(value.trim());\n      return this;","sourceCodeStart":217,"sourceCodeEnd":253,"githubUrl":"https://github.com/didi/DoKit/blob/626827cddb2feb2f3aee87a52a064b4e5ca2bed4/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/network/common/CommonHeaders.java#L217-L253","documentation":"Thrown by CommonHeaders.Builder.add(String line) when the given header line contains no ':' character. The method splits a raw header line into name and value at the first colon; a colon-free line cannot be split so it is rejected.","triggerScenarios":"Calling builder.add(\"Content-Type application/json\") (missing colon), or feeding it a line that is a bare value, a comment, or a trailing empty/malformed line from a raw header block split by newline without per-line validation.","commonSituations":"Parsing pasted or recorded HTTP header blocks (e.g. from DoKit mock templates or curl exports) where one line is a wrapped continuation or simply malformed; status lines accidentally included in the header list.","solutions":["Check indexOf(':') per line before calling add, and skip/log lines without one","Fix the header-block parser to only yield header lines, not status lines or continuations","For continuation lines (obs-fold), append to the previous header's value instead of adding a new line"],"exampleFix":"// before\nfor (String line : rawHeaderBlock.split(\"\\n\")) builder.add(line); // throws on \"HTTP/1.1 200 OK\"\n\n// after\nfor (String line : rawHeaderBlock.split(\"\\n\")) {\n  if (line.contains(\":\")) builder.add(line);\n}","handlingStrategy":"validation","validationCode":"for (String line : headerBlock.split(\"\\r?\\n\")) {\n  if (line != null && line.indexOf(':') != -1) builder.add(line);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Filter raw header blocks line-by-line: only lines containing ':' are headers","Exclude status lines and wrapped continuations before feeding Builder.add(String)"],"tags":["android","network","headers","parsing"],"backgroundTag":null,"analyzedSha":"626827cddb2feb2f3aee87a52a064b4e5ca2bed4","analyzedAt":"2026-08-14T12:45:58.758Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}