Skip to content

Bug: Sessions intermittently show raw session ID instead of display name #1561

@quay-devel

Description

@quay-devel

Description

Sessions in the UI sometimes display a friendly generated name and sometimes remain showing the raw session ID (session-<UUID>). This is a regression that became more visible after the v0.2.6 release.

Root Cause Analysis

The display name generation system has two independent code paths with a gap between them:

Path A — CreateSession handler (sessions.go:1209-1213): When initialPrompt is provided without displayName, fires GenerateDisplayNameAsync() in a fire-and-forget goroutine with a 10-second timeout. No retry on failure.

Path B — AG-UI proxy (agui_proxy.go:976-1017): On every /agui/run POST, checks if display name is missing and generates from the first user message. However, it intentionally skips messages matching initialPrompt (lines 1005-1009) to prevent double-generation.

The bug: If Path A fails (API timeout, Vertex errors, credential issues), Path B refuses to act as a fallback because the runner's initial prompt message matches the skip condition. The session is permanently stuck with the raw session ID until the user sends a second message — which may never happen for scheduled or one-shot sessions.

The existing guards (ShouldGenerateDisplayName at line 1011 and updateSessionDisplayNameInternal race check at display_name.go:302-307) already prevent double-generation without the initialPrompt skip, making lines 1005-1009 redundant protection that creates a single point of failure.

Likely Regression Trigger

Commit 85af3da (PR #1453, merged between v0.2.5 and v0.2.6) changed the Vertex AI CLOUD_ML_REGION default from us-east5 to global. If the global endpoint has higher latency or intermittent failures, the 10-second timeout in Path A would be exceeded more often, making this pre-existing design flaw more visible.

Affected Sessions

Creation Path Has initialPrompt Affected?
New Session Page Yes Yes — no fallback if Path A fails
Create Dialog (prompt, no displayName) Yes Yes
Scheduled Sessions Yes Yes — worst case, never gets a second message
Create Dialog (with displayName) N/A No — user-provided name
Create Dialog (no prompt) No No — Path B handles on first message
Clone Session N/A No — inherits name

Proposed Fix

Delete lines 1005-1009 in agui_proxy.go (the initialPrompt skip). The existing guards already prevent double-generation:

  • ShouldGenerateDisplayName(spec) returns false if displayName is already set (handles Path A success)
  • updateSessionDisplayNameInternal first-write-wins check (handles concurrent races)

This is a 5-line deletion with no new code required.

Steps to Reproduce

  1. Create a session with initialPrompt and no displayName (e.g., via the New Session page)
  2. If the Claude Haiku API call in GenerateDisplayNameAsync fails or times out, the session will show its raw session-<UUID> name in the sessions list
  3. The name will remain as the raw ID until the user manually sends a second message through the chat

Environment

  • Platform version: v0.2.6
  • Component: backend (components/backend/handlers/display_name.go, components/backend/websocket/agui_proxy.go)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions