Skip to content

Fix timestamp message search hanging on empty partitions and 'topic undefined' 404 on navigation - #2623

Closed
jvorcak wants to merge 2 commits into
masterfrom
jv/fix-timestamp-search-and-undefined-topic-nav
Closed

Fix timestamp message search hanging on empty partitions and 'topic undefined' 404 on navigation#2623
jvorcak wants to merge 2 commits into
masterfrom
jv/fix-timestamp-search-and-undefined-topic-nav

Conversation

@jvorcak

@jvorcak jvorcak commented Aug 31, 2026

Copy link
Copy Markdown
Collaborator

Fixes two customer-reported issues (Zendesk ticket 7199).

1. Backend: `[unknown] request was cancelled while waiting for messages` with Timestamp start offset

A start offset resolved by timestamp is `-1` on an empty partition. `calculateConsumeRequests` clamped it to `highWaterMark - 1`, which is `-1` again for an empty partition — and kgo interprets `At(-1)` as "start at the end", i.e. an indefinite live tail. The round-robin allocator also assigned a message to such partitions, so the request could never be satisfied and only ended via cancellation after the server deadline (~35s). One empty partition in an otherwise populated topic was enough to make every timestamp search fail this way.

Fix: exclude partitions with nothing to consume (`high <= low`) from the consume request (except deliberate live tail), and complete immediately — instead of returning an error — when all partitions are empty.

Verified live via `buf curl` against the streaming RPC:

  • empty 3-partition topic + timestamp offset: before → hang + cancellation error after 35s; after → `done` in 2ms
  • topic with data in one of three partitions: before → messages returned but request still dies after 35s; after → messages returned, `done` in 7ms

New unit tests: `TestCalculateConsumeRequests_EmptyPartitions`, `TestCalculateConsumeRequests_AllPartitionsEmpty` (live tail still includes empty partitions).

2. Frontend: 404 "The topic 'undefined' does not exist" when navigating away mid-fetch

nuqs flushes queued URL updates inside `startTransition(() => navigate({ to, from }))`. Frequent synchronous re-renders during an in-flight message search ("Fetching data...") keep preempting that transition; when the user clicks away, their navigation commits first and the deferred flush then runs `navigate` with a `from` route that is no longer matched. TanStack Router interpolates the missing `$topicName` param as the literal string `undefined`, navigating to `/topics/undefined` — a persistent 404 (console warning: `Could not find match for from: /topics/$topicName/`).

Fix: wrap the tanstack-router nuqs adapter (`utils/nuqs-tanstack-adapter.tsx`) so a flush is dropped when its originating route is no longer in the router's pending/current matches, checked at flush time.

Verified with a headless-browser repro (empty topic, start a hanging search, click "Topics" while "Fetching data..." shows): before → `/topics/undefined` + persistent 404, 3/3 runs; after → lands on `/topics/` normally.

Repro (for QA)

  1. `rpk topic create repro-empty -p 3`
  2. Topic → Messages tab → Start Offset → Timestamp (any time) → search errors after ~35s (issue 1)
  3. While "Fetching data..." shows (use Latest / Live on the empty topic for a stable window), click Topics in the sidebar → URL becomes `/topics/undefined` (issue 2)

Testing

  • `go test ./pkg/console/`, `go vet`, `gofmt` clean
  • frontend `type:check`, `lint`, full `bun run test` (1259 tests) pass

A start offset resolved by timestamp is -1 on an empty partition, which was
clamped to highWaterMark-1 (= -1 again), and kgo interprets At(-1) as 'start
at the end' — an indefinite live tail. The round-robin also allocated a
message to such partitions, so the request could never be satisfied and only
ended via cancellation: '[unknown] request was cancelled while waiting for
messages'.

Exclude partitions with nothing to consume (high <= low) from the consume
request, except for deliberate live tail, and complete immediately (instead
of erroring) when all partitions are empty.

Reference: Zendesk ticket 7199.
nuqs flushes queued URL updates inside startTransition(() => navigate({ to,
from })). Frequent synchronous re-renders (e.g. message-search progress) keep
preempting that transition; when the user navigates away, their navigation
commits first and the deferred flush runs navigate with a 'from' route that
is no longer matched. TanStack Router then interpolates the missing path
params as the literal string 'undefined', navigating to /topics/undefined
and showing a persistent 404 ("The topic 'undefined' does not exist").

Wrap the tanstack-router adapter so a flush is dropped when its originating
route is no longer in the router's pending/current matches.

Reference: Zendesk ticket 7199.
@github-actions

Copy link
Copy Markdown
Contributor

Clean — no registry drift, off-token colours, or ad-hoc classes

App: frontend · Scope: diff vs origin/master · Files: 3

Count
⚠️ Outdated registry components 0
🛠 Locally-modified components 0
❓ Unknown to registry 0
🎨 Off-token palette colours 0
🔢 Ad-hoc utility classes 0

Generated by lookout audit-changes.

@jvorcak jvorcak closed this Aug 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant