{"record":{"id":"c6b906506038e9e3","repo":"eclipse-vertx/vert.x","slug":"unexpected-trailing-token","errorCode":null,"errorMessage":"Unexpected trailing token","messagePattern":"Unexpected trailing token","errorType":"exception","errorClass":"DecodeException","httpStatus":null,"severity":"error","filePath":"vertx-core/src/main/java/io/vertx/core/json/jackson/DatabindCodec.java","lineNumber":135,"sourceCode":"      return DatabindCodec.mapper.getFactory().createParser(str);\n    } catch (IOException e) {\n      throw new DecodeException(\"Failed to decode:\" + e.getMessage(), e);\n    }\n  }\n\n  public static <T> T fromParser(JsonParser parser, Class<T> type) throws DecodeException {\n    T value;\n    JsonToken remaining;\n    try {\n      value = DatabindCodec.mapper.readValue(parser, type);\n      remaining = parser.nextToken();\n    } catch (Exception e) {\n      throw new DecodeException(\"Failed to decode:\" + e.getMessage(), e);\n    } finally {\n      close(parser);\n    }\n    if (remaining != null) {\n      throw new DecodeException(\"Unexpected trailing token\");\n    }\n    if (type == Object.class) {\n      value = (T) adapt(value);\n    }\n    return value;\n  }\n\n  private static <T> T fromParser(JsonParser parser, TypeReference<T> type) throws DecodeException {\n    T value;\n    try {\n      value = DatabindCodec.mapper.readValue(parser, type);\n    } catch (Exception e) {\n      throw new DecodeException(\"Failed to decode:\" + e.getMessage(), e);\n    } finally {\n      close(parser);\n    }\n    if (type.getType() == Object.class) {\n      value = (T) adapt(value);","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java/io/vertx/core/json/jackson/DatabindCodec.java#L117-L153","documentation":"After Jackson reads the requested value, fromParser checks for another token; if the input contains extra non-whitespace content after the first value it throws DecodeException 'Unexpected trailing token'. Vert.x decodes exactly one JSON value per call.","triggerScenarios":"Json.decodeValue('{\"a\":1} {\"b\":2}') — two JSON objects concatenated; newline-delimited JSON fed as a whole; logs/concatenated payloads with a stray second value; invisible trailing characters that Jackson still tokenizes.","commonSituations":"NDJSON streams consumed without splitting on newlines; accumulating multiple frames into one buffer before decoding; copy-paste of several JSON documents into one config file.","solutions":["Decode one value at a time; split NDJSON by '\\n' and decode each line.","Trim the payload and inspect the tail for extra objects/values.","If multiple values are expected, use JacksonParser streaming manually or a JSON-lines parser.","Fix the producer to send exactly one JSON document per message."],"exampleFix":"// before\nJson.decodeValue(line1 + line2, Config.class); // trailing token\n// after\nfor (String line : payload.split(\"\\n\")) {\n  Config c = Json.decodeValue(line, Config.class);\n}","handlingStrategy":"validation","validationCode":"String t = raw.trim();\nint end = indexOfMatchingValue(t); // or simply: assert exactly one top-level value\nif (countTopLevelValues(t) > 1) throw new IllegalStateException(\"payload contains multiple JSON values\");","typeGuard":"static boolean isSingleJsonValue(String s) {\n  try {\n    JsonParser p = new ObjectMapper().getFactory().createParser(s);\n    p.nextToken();\n    boolean single = p.nextToken() == null;\n    p.close();\n    return single;\n  } catch (Exception e) { return false; }\n}","tryCatchPattern":"try {\n  Config c = Json.decodeValue(raw, Config.class);\n} catch (DecodeException e) {\n  if (\"Unexpected trailing token\".equals(e.getMessage())) {\n    // split NDJSON or fix producer framing\n  }\n}","preventionTips":["Split newline-delimited JSON before decoding each line.","Never concatenate messages/frames into one buffer prior to decoding.","Trim and inspect payload tails for stray characters."],"tags":["json","decode","trailing-token","ndjson"],"backgroundTag":"json-parse-error","analyzedSha":"fb308bd8c3f12c79f4ae89bef67fadf6c80d036e","analyzedAt":"2026-09-06T11:37:12.241Z","contentChangedAt":"2026-09-06T11:37:12.241Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}