{"record":{"id":"f85bd7f9b2ad76e5","repo":"provectus/kafka-ui","slug":"seekto-should-be-set-if-seektype-is-seektype","errorCode":null,"errorMessage":"seekTo should be set if seekType is ${seekType}","messagePattern":"seekTo should be set if seekType is (.+?)","errorType":"validation","errorClass":"ValidationException","httpStatus":400,"severity":"error","filePath":"kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/MessagesController.java","lineNumber":160,"sourceCode":"\n    return validateAccess(context).then(\n        createTopicMessage.flatMap(msg ->\n            messagesService.sendMessage(getCluster(clusterName), topicName, msg).then()\n        ).map(ResponseEntity::ok)\n    ).doOnEach(sig -> audit(context, sig));\n  }\n\n  /**\n   * The format is [partition]::[offset] for specifying offsets\n   * or [partition]::[timestamp in millis] for specifying timestamps.\n   */\n  @Nullable\n  private Map<TopicPartition, Long> parseSeekTo(String topic, SeekTypeDTO seekType, List<String> seekTo) {\n    if (seekTo == null || seekTo.isEmpty()) {\n      if (seekType == SeekTypeDTO.LATEST || seekType == SeekTypeDTO.BEGINNING) {\n        return null;\n      }\n      throw new ValidationException(\"seekTo should be set if seekType is \" + seekType);\n    }\n    return seekTo.stream()\n        .map(p -> {\n          String[] split = p.split(\"::\");\n          if (split.length != 2) {\n            throw new IllegalArgumentException(\n                \"Wrong seekTo argument format. See API docs for details\");\n          }\n\n          return Pair.of(\n              new TopicPartition(topic, Integer.parseInt(split[0])),\n              Long.parseLong(split[1])\n          );\n        })\n        .collect(toMap(Pair::getKey, Pair::getValue));\n  }\n\n  @Override","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/provectus/kafka-ui/blob/83b5a60cc08501b570a0c4d0b4cdfceb1b88d6b7/kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/MessagesController.java#L142-L178","documentation":"MessagesController.parseSeekTo resolves the seek position for the GET messages API. If seekType is OFFSET, TIMESTAMP (or otherwise neither LATEST nor BEGINNING), an explicit seekTo list is mandatory; when it is null or empty a ValidationException is thrown.","triggerScenarios":"Calling GET /api/clusters/{c}/topics/{t}/messages with seekType=OFFSET or TIMESTAMP but omitting seekTo, or sending an empty seekTo list.","commonSituations":"API clients using the generated SDK defaults that leave seekTo unset; frontend filters requesting offsets without computing the offset list; Swagger 'try it out' leaving seekTo blank.","solutions":["Provide seekTo entries (format `partition::offset` for OFFSET, `partition::timestampMillis` for TIMESTAMP)","Use seekType=BEGINNING or LATEST if you don't need specific positions","Fix the client to always send seekTo when a non-default seekType is used"],"exampleFix":"// before\nGET /api/clusters/local/topics/my-topic/messages?seekType=OFFSET\n// after\nGET /api/clusters/local/topics/my-topic/messages?seekType=OFFSET&seekTo=0::42&seekTo=1::17","handlingStrategy":"validation","validationCode":"function buildMessagesQuery(seekType, seekTo) {\n  if (seekType !== 'LATEST' && seekType !== 'BEGINNING' && (!seekTo || seekTo.length === 0)) {\n    throw new Error('seekTo is required for seekType ' + seekType);\n  }\n  return { seekType, seekTo };\n}","typeGuard":null,"tryCatchPattern":"try {\n  const res = await api.getMessages(params);\n} catch (e) {\n  if (e.status === 400 && /seekTo should be set/.test(e.message)) {\n    params.seekTo = computeSeekTo(params.seekType);\n    retry();\n  }\n}","preventionTips":["Default to seekType=BEGINNING or LATEST when no explicit positions are needed","Compute seekTo from partition metadata before calling the API","Add client-side request validation mirroring the server contract"],"tags":["rest-api","validation","kafka","query-parameter"],"backgroundTag":"missing-required-argument","analyzedSha":"83b5a60cc08501b570a0c4d0b4cdfceb1b88d6b7","analyzedAt":"2026-09-08T04:35:39.002Z","contentChangedAt":"2026-09-08T04:35:39.002Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}