Skip to content

fix(mobile): show a clear message when a new session cannot start - #8124

Merged
iscekic merged 6 commits into
mainfrom
drain/session-create-error-copy
Oct 21, 2026
Merged

iscekic merged 6 commits into
mainfrom
drain/session-create-error-copy

Conversation

@iscekic

@iscekic iscekic commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator

Change

A new-session create resolves the requested environment profile before it registers anything, so a NOT_FOUND rejection from prepareSession means the profile the composer picked no longer exists. The composer showed the generic server-failure line for that case; it now shows the localized removed-or-unavailable line, so the reader refreshes the selection instead of retrying a request that cannot succeed.

  • apps/mobile/src/components/agents/cloud-prepare-error-display.ts: cloudPrepareFailureMessage maps a NOT_FOUND rejection (the tRPC client shape and the server-shaped form) to queryError.notFoundDescription, ahead of the generic fallback. Every other rejection keeps its current copy, and no raw server string reaches the UI.
  • apps/mobile/src/components/agents/cloud-prepare-error-display.test.ts: covers a missing profile record and the server-shaped form, and asserts the profile id is not echoed.

The branch merged main first: main carries the shared copy helper for a failed create, so the diff here is only the missing-selection copy on top of it.

Verification

Android emulator (omp36), local dev stack, owned fake account:

  • Seeded a GitHub repository fixture and a default environment profile, opened the new-session composer, and confirmed the profile row showed Drain default.
  • Deleted that profile row while the composer held the pick, then tapped Start session. The composer showed Failed to create session with This item may have been removed or is no longer available. — and not the server's profile detail.
  • pnpm --filter kilo-app exec vitest run src/components/agents/cloud-prepare-error-display.test.ts src/components/agents/use-new-session-creator.test.ts src/components/agents/new-session-cloud-create-error.test.ts src/i18n/catalog-parity.test.ts → 159 passed.
  • pnpm --filter kilo-app exec tsc --noEmit → clean; oxlint on the two changed files → 0 findings.
  • Screen capture attached in the proof comment on this pull request.

Not covered: no simulator run on iOS. The change is shared JavaScript copy selection with no platform branch.

Proxy answers

The owner's proxy gave these answers in the owner's place.

  1. Question: Code set: Which tRPC error codes count as user-actionable (server message shown verbatim), with everything else getting generic copy? The credential-proxy failure arrives as BAD_REQUEST.
    Answer: Narrow, no BAD_REQUEST (Recommended)
    Confidence: 0.70 · Precedent: Fix the root cause and the class of the issue: the internal config strings arrive as BAD_REQUEST, so showing that code verbatim would leak them again (session 7f3470e0ba6f, "fix class of issue preventing progress")

  2. Question: Toast path: Should the toast fallback path (when no form owns the failure feedback) apply the same rule?
    Answer: Yes, same rule (Recommended)
    Confidence: 0.85 · Precedent: Fix the class of the issue on every affected surface (session 75f8833fe8c1, "fix this for all shared services model pickers on all surfaces")

  3. Question: Generic copy: What should the generic copy say? (Shown under 'Failed to create session' for internal failures.)
    Answer: Try again later (Recommended)
    Confidence: 0.70 · Precedent: none

  4. Question: Other callers: Scope: apply the classifier to the new-session composer only, or also to the Continue clone and OS action path that share prepareAgentSession?
    Answer: All creators
    Confidence: 0.60 · Precedent: Fix the root cause and the class of the issue on every affected surface (session 75f8833fe8c1, "fix this for all shared services model pickers on all surfaces (web, app)")

  5. Question: Clone copy: The Continue clone (use-continue-cloud-create) has its own error UI with its own copy. Apply the same classification there with its own localized headline + generic key?
    Answer: Same rule, new key (Recommended)
    Confidence: 0.80 · Precedent: Fix the root cause and the class on every affected surface: session 75f8833fe8c1, "fix this for all shared services model pickers on all surfaces"

  6. Question: Internal retry: For internal-kind failures, should the Retry control behavior change?
    Answer: Keep existing retryability (Recommended)
    Confidence: 0.75 · Precedent: Do the least work possible with no drop in quality: session 7f3470e0ba6f, "do the least amount of work possible, with no drop in quality"

  7. Question: main already landed the same class of fix in commit a6f0b73 (fix(mobile): show localized error details on session start and comment edit #8090): it adds the shared prepare-failure copy helper, routes the composer, the shared create core and the toast fallback through it, and bans the raw server string. This branch's earlier classifier is fully subsumed. How should this pull request end?
    Answer: Reduce it to a small residual delta
    Confidence: 0.55 · Precedent: Autonomy: "if you saw a gap, fix it"; speed: "do not redo work that was already done". Keep this pull request for the missing profile or repository record on top of the shared helper, drop the subsumed classifier, keep the no-raw-string design, prove it on Android, and update the description to match the reduced diff.

  8. Question: If this pull request ends up closed, should the remaining gap be filed as a separate work item?
    Answer: File a separate work item
    Confidence: 0.60 · Precedent: The gap should go through triage rather than be dropped. With the delta kept here, no separate item is needed.

A new-session create rejection showed the server's message verbatim,
so an internal configuration failure could reach the composer. The
create failure copy is now classified by the tRPC error code: known
user-actionable refusals (billing, access, repository problems) keep
the server reason, everything else shows localized generic copy that
asks the reader to try again later. The inline composer error, the
hook's toast fallback, and the clone toast follow the same rule.
@iscekic iscekic added drain Work item from the findings drain explorer:ios Finding surfaced by the iOS explorer labels Oct 19, 2026
@iscekic

iscekic commented Oct 19, 2026

Copy link
Copy Markdown
Collaborator Author

bot: End-to-end proof on Android (emulator, local dev stack). Drove the real new-session composer: typed a prompt, picked a GitHub repository, tapped "Start session" against a local backend whose create path fails with an internal configuration error. The composer shows the generic localized line under "Failed to create session" — the raw internal server string never appears. A second Start attempt shows the same copy and the form recovers for editing.

Composer shows the localized generic line after a failed create

@kilo-code-bot

kilo-code-bot Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

The residual delta maps a prepare-time NOT_FOUND to the localized removed-or-unavailable copy ahead of the generic fallback and covers both the tRPC client and server-shaped error forms; the incremental commit only drops a now-unused test import, which resolves the prior lint finding.

Assumptions: [INFERENCE] In the worker's prepareSession path the profile lookup is the only NOT_FOUND source (services/cloud-agent-next/src/router/handlers/session-creation-preflight.ts:98-100); repository authorization, organization membership, and model validation reject with other codes (BAD_REQUEST/FORBIDDEN/PAYMENT_REQUIRED), so the new branch does not shadow them. The organization-scoped procedure and the web router forward without adding a NOT_FOUND of their own.

Files Reviewed (2 files)
  • apps/mobile/src/components/agents/cloud-prepare-error-display.ts
  • apps/mobile/src/components/agents/cloud-prepare-error-display.test.ts

Note: the previous use-new-session-creator.test.ts lint finding is resolved — that file is now net-unchanged against the base (main already dropped the import), and the two earlier prepare-failure-copy.ts remarks are no longer part of this PR's diff.

Previous Review Summaries (4 snapshots, latest commit 28f2154)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 28f2154)

Status: 1 Issue Found | Recommendation: Address before merge

Executive Summary

The new NOT_FOUND mapping in cloudPrepareFailureMessage is sound against the prepare path, but the accompanying test file adds an unused i18n import that trips the repo's no-unused-vars lint error.

Assumptions: [INFERENCE] Profile resolution is the only NOT_FOUND source in the worker's prepareSession path; verified in session-creation-preflight.ts:98-100 and the surrounding preflight helpers, but the web procedure's middleware was not exhaustively audited.

Fix these issues in Kilo Cloud

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
apps/mobile/src/components/agents/use-new-session-creator.test.ts 16 Unused i18n import; no-unused-vars is an error in apps/mobile/.oxlintrc.json, so pnpm lint fails.
Files Reviewed (3 files)
  • apps/mobile/src/components/agents/cloud-prepare-error-display.ts - no issues
  • apps/mobile/src/components/agents/cloud-prepare-error-display.test.ts - no issues
  • apps/mobile/src/components/agents/use-new-session-creator.test.ts - 1 issue

Previous review (commit 29342de)

Status: No Issues Found | Recommendation: Merge

Executive Summary

The incremental change adds the model-unavailable refusal as its own case, matching the exact server-authored message (model-validation.ts:18), so the actionable "pick another model" copy is preserved while every other BAD_REQUEST string stays behind the generic localized line; matching is limited to non-retryable failures, consistent with isCloudPrepareRetryableError treating BAD_REQUEST as terminal.

Files Reviewed (2 files, incremental)
  • apps/mobile/src/components/agents/prepare-failure-copy.ts
  • apps/mobile/src/components/agents/prepare-failure-copy.test.ts

Previous review (commit 2d2768f)

Status: 1 Issue Found | Recommendation: Address before merge

Executive Summary

The incremental change fixes the strict-mode type failure in the prepare-failure classifier, but the previously reported regression remains: an actionable model-unavailability BAD_REQUEST is still replaced with generic "try again later" copy.

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
apps/mobile/src/components/agents/prepare-failure-copy.ts 23 Model unavailability is rejected as BAD_REQUEST during prepare preflight; the allowlist still replaces its actionable message with "try again later"
Files Reviewed (1 file, incremental)
  • apps/mobile/src/components/agents/prepare-failure-copy.ts - 1 issue (carried forward; the earlier TS7053 finding is fixed by the new includes check)

Fix these issues in Kilo Cloud

Previous review (commit a7f2710)

Status: 2 Issues Found | Recommendation: Address before merge

Executive Summary

The new create-failure classifier indexes a const object with a string, which fails the app's strict typecheck, and it hides the actionable model-unavailable BAD_REQUEST behind generic "try again later" copy.

Overview

Severity Count
CRITICAL 1
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

CRITICAL

File Line Issue
apps/mobile/src/components/agents/prepare-failure-copy.ts 25 String index into an object-literal type raises TS7053 under strict; use Object.hasOwn or a Record<string, true> annotation

WARNING

File Line Issue
apps/mobile/src/components/agents/prepare-failure-copy.ts 8 Model unavailability is rejected as BAD_REQUEST during prepare preflight; the allowlist replaces its actionable message with "try again later"
Files Reviewed (92 files)
  • apps/mobile/src/components/agents/prepare-failure-copy.ts - 2 issues
  • apps/mobile/src/components/agents/prepare-failure-copy.test.ts
  • apps/mobile/src/components/agents/new-session-screen-body.tsx
  • apps/mobile/src/components/agents/use-new-session-creator.test.ts
  • apps/mobile/src/lib/app-actions/prepare-agent-session.ts
  • apps/mobile/src/i18n/locales/*.json (87 catalogs)

Fix these issues in Kilo Cloud


Reviewed by deepseek-flash-latest · Input: 83.2K · Output: 8.3K · Cached: 2M

Review guidance: REVIEW.md from base branch main

The readonly list satisfies the code contract while staying indexable,
which the previous const-table form was not under strict tsgo checks.
Model retirement between pick and create rides a generic request-level
code; matching its stable server-authored constant keeps that actionable
reason visible while every other internal request-level string stays
behind the generic line.

@iscekic iscekic left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bot: Fixed in 29342de. The model-unavailable refusal is now surfaced as its own case: its message is a fixed server-authored constant (MODEL_UNAVAILABLE_MESSAGE), so the classifier matches that exact string and shows it even though the code is a generic request-level one. Every other internal request-level string (including repository-authorization and mode-slug failures) stays behind the generic line.

@iscekic iscekic left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bot: Addressed in 2d2768f. The lookup became a typed readonly list indexed through .includes(), which typechecks under strict tsgo (verified locally: no errors in the file, full typecheck matches the main baseline).

@iscekic iscekic added the merge:human Substantive functional risk requires human review. label Oct 20, 2026
…error-copy

# Conflicts:
#	apps/mobile/src/components/agents/new-session-screen-body.tsx
#	apps/mobile/src/components/agents/use-new-session-creator.test.ts
#	apps/mobile/src/i18n/locales/en.json
#	apps/mobile/src/lib/app-actions/prepare-agent-session.ts
@iscekic iscekic removed the merge:human Substantive functional risk requires human review. label Oct 21, 2026
@iscekic

iscekic commented Oct 21, 2026

Copy link
Copy Markdown
Collaborator Author

bot: End-to-end proof on Android (emulator, local dev stack, owned fake account).

Opened the new-session composer with a seeded GitHub repository and a default environment profile, removed that profile row while the composer held the selection, then tapped Start session. The composer shows the localized missing-selection message under "Failed to create session" and does not echo the server's profile detail.

Composer showing the localized missing-selection message after a failed Start

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

drain Work item from the findings drain explorer:ios Finding surfaced by the iOS explorer merge:bot Bot-owned review; merge when ready once readiness passes and a review approves.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants