Skip to content

fix(desktop): structured error_kind on chat_agent_error telemetry (#9342)#9348

Open
kodjima33 wants to merge 1 commit into
mainfrom
watchdog/issue-9342-chat-error-kind
Open

fix(desktop): structured error_kind on chat_agent_error telemetry (#9342)#9348
kodjima33 wants to merge 1 commit into
mainfrom
watchdog/issue-9342-chat-error-kind

Conversation

@kodjima33

@kodjima33 kodjima33 commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Bug

Issue #9342 (p1, reliability): macOS beta chat requests fail with AI not available: bridge failed to start — the dominant beta chat error (~21.8% of active beta/newer users in the last 24h). Acceptance criterion #3 asks for telemetry structured enough to distinguish missing install, launch failure, crash, and provider/config errors.

Root cause (observability gap)

In ChatProvider's two chat_agent_error emit paths, every failure that isn't rendered as a ChatErrorState card is flattened into a single opaque error string. This bucket mixes:

  • non-BridgeError launch failures (the actual Process spawn errors behind "bridge failed to start"), and
  • BridgeError cases that ChatErrorState.from() maps to nil: .agentError, .agentRuntimeFailure, .quotaExceeded, .encodingError, .requestAlreadyActive, .stopped.

So PostHog can't tell a missing install from a launch failure, a crash, or a provider/config error — exactly what the issue needs to triage this p1.

Fix

  • Add BridgeError.telemetryKind(for:) — a stable, low-cardinality category for any Error. BridgeError cases map to bridge.* kinds; non-BridgeError launch failures surface the NSError domain+code (e.g. POSIX ENOENT = missing executable / install problem, distinct from a crash).
  • Attach it as an error_kind property on both chat_agent_error emit sites via a new optional chatAgentError(errorKind:) param.
  • The existing error / raw_error fields are unchanged, so current dashboards keep working.

No user-facing behavior change — telemetry enrichment only.

Tests / verification

  • New regression test testTelemetryKindDistinguishesFailureModes (distinct causes → distinct kinds; missing-binary ≠ crash).
  • xcrun swift build -c debug --package-path DesktopBuild complete.
  • xcrun swift test --filter ChatErrorStateMappingTests3/3 pass.

🤖 automated by hourly watchdog; opened for review, not merged. This is a diagnostics change — it does not itself resolve the underlying bridge-start failure, so it is intentionally not auto-merged.

Review in cubic

…#9342)

The macOS chat 'AI not available: bridge failed to start' error dominates
beta chat failures (~21.8% of active beta users), but every non-carded
failure — non-BridgeError launch errors plus BridgeError cases that
ChatErrorState.from() maps to nil (.agentError, .agentRuntimeFailure,
.quotaExceeded, .encodingError, .requestAlreadyActive, .stopped) — is
flattened into one opaque 'error' string, so PostHog cannot tell a missing
install from a launch failure, a crash, or a provider/config error.

Add BridgeError.telemetryKind(for:) and attach it as a low-cardinality
'error_kind' property on both chat_agent_error emit sites. Non-BridgeError
launch failures surface the NSError domain+code (POSIX ENOENT = missing
executable / install problem), distinct from crashes. Addresses issue
#9342 acceptance criterion #3 (structured fields to distinguish failure
modes). No behavior change; existing 'error' string preserved.

Regression test: testTelemetryKindDistinguishesFailureModes.
Verified: xcrun swift build -c debug (Build complete) + swift test
--filter ChatErrorStateMappingTests (3/3 pass).
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