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
- Create a session with
initialPrompt and no displayName (e.g., via the New Session page)
- 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
- 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)
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): WheninitialPromptis provided withoutdisplayName, firesGenerateDisplayNameAsync()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/runPOST, checks if display name is missing and generates from the first user message. However, it intentionally skips messages matchinginitialPrompt(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 (
ShouldGenerateDisplayNameat line 1011 andupdateSessionDisplayNameInternalrace check atdisplay_name.go:302-307) already prevent double-generation without theinitialPromptskip, 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_REGIONdefault fromus-east5toglobal. 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
Proposed Fix
Delete lines 1005-1009 in
agui_proxy.go(theinitialPromptskip). The existing guards already prevent double-generation:ShouldGenerateDisplayName(spec)returnsfalseif displayName is already set (handles Path A success)updateSessionDisplayNameInternalfirst-write-wins check (handles concurrent races)This is a 5-line deletion with no new code required.
Steps to Reproduce
initialPromptand nodisplayName(e.g., via the New Session page)GenerateDisplayNameAsyncfails or times out, the session will show its rawsession-<UUID>name in the sessions listEnvironment
components/backend/handlers/display_name.go,components/backend/websocket/agui_proxy.go)