{"record":{"id":"714d0dffaa44bf8b","repo":"didi/DoKit","slug":"expected-alternating-header-names-and-values","errorCode":null,"errorMessage":"Expected alternating header names and values","messagePattern":"Expected alternating header names and values","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/network/common/CommonHeaders.java","lineNumber":163,"sourceCode":"  }\n\n  private static String get(String[] namesAndValues, String name) {\n    for (int i = namesAndValues.length - 2; i >= 0; i -= 2) {\n      if (name.equalsIgnoreCase(namesAndValues[i])) {\n        return namesAndValues[i + 1];\n      }\n    }\n    return null;\n  }\n\n  /**\n   * Returns headers for the alternating header names and values. There must be an even number of\n   * arguments, and they must alternate between header names and values.\n   */\n  public static CommonHeaders of(String... namesAndValues) {\n    if (namesAndValues == null) throw new NullPointerException(\"namesAndValues == null\");\n    if (namesAndValues.length % 2 != 0) {\n      throw new IllegalArgumentException(\"Expected alternating header names and values\");\n    }\n\n    // Make a defensive copy and clean it up.\n    namesAndValues = namesAndValues.clone();\n    for (int i = 0; i < namesAndValues.length; i++) {\n      if (namesAndValues[i] == null) throw new IllegalArgumentException(\"Headers cannot be null\");\n      namesAndValues[i] = namesAndValues[i].trim();\n    }\n\n    // Check for malformed headers.\n    for (int i = 0; i < namesAndValues.length; i += 2) {\n      String name = namesAndValues[i];\n      String value = namesAndValues[i + 1];\n      if (name.length() == 0 || name.indexOf('\\0') != -1 || value.indexOf('\\0') != -1) {\n        throw new IllegalArgumentException(\"Unexpected header: \" + name + \": \" + value);\n      }\n    }\n","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/didi/DoKit/blob/626827cddb2feb2f3aee87a52a064b4e5ca2bed4/Android/dokit/src/main/java/com/didichuxing/doraemonkit/kit/network/common/CommonHeaders.java#L145-L181","documentation":"Thrown by CommonHeaders.of(String... namesAndValues) when the number of elements is odd. Headers are stored as a flat alternating array [name0, value0, name1, value1, ...]; an odd count means a name is missing its value, which would corrupt every subsequent pair during reads.","triggerScenarios":"Calling CommonHeaders.of(\"Content-Type\", \"application/json\", \"Authorization\") — a trailing header name with no value; commonly happens when dynamically appending a single header to an array without extending it by two slots.","commonSituations":"Building header arrays in loops that append a name and conditionally skip the value; copy-paste mistakes when adding an extra header to a literal array.","solutions":["Ensure headers are always added as name+value pairs — check that args.length % 2 == 0 before the call","Fix the construction site: every add of a header name must be paired with its value in the same statement","Switch to CommonHeaders.Builder and call add(name, value) per header so pairs are structurally guaranteed"],"exampleFix":"// before\nCommonHeaders.of(\"Accept\", \"*/*\", \"X-Trace-Id\"); // odd count\n\n// after\nCommonHeaders.of(\"Accept\", \"*/*\", \"X-Trace-Id\", traceId);","handlingStrategy":"validation","validationCode":"if (headerArray != null && headerArray.length % 2 == 0) { CommonHeaders.of(headerArray); } else { /* fix pairs upstream */ }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always append headers in name+value pairs at the same call site","Assert array.length % 2 == 0 in debug builds where headers are assembled"],"tags":["android","network","headers","validation"],"backgroundTag":null,"analyzedSha":"626827cddb2feb2f3aee87a52a064b4e5ca2bed4","analyzedAt":"2026-08-14T12:45:58.758Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}