Skip to content

[APP-5168] Demote harness-availability refresh failure from Sentry to a warn log - #14703

Closed
warp-agent-staging[bot] wants to merge 1 commit into
masterfrom
factory/app-5168-demote-harness-fetch-error
Closed

[APP-5168] Demote harness-availability refresh failure from Sentry to a warn log#14703
warp-agent-staging[bot] wants to merge 1 commit into
masterfrom
factory/app-5168-demote-harness-fetch-error

Conversation

@warp-agent-staging

@warp-agent-staging warp-agent-staging Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Description

HarnessAvailabilityModel::refresh (app/src/ai/harness_availability.rs) is a best-effort background refresh of the harness list. On failure the model keeps using the cached list — or default_harnesses() (Oz enabled) — and the picker stays usable. Its error arm nonetheless called report_error!, which is reserved for actionable defects and is the only path (besides panics) that creates a Sentry issue.

The result is Sentry issue WARP-CLIENT-BETA-STABLE-7M3C: ~275k events across ~112k users, overwhelmingly HttpError: received non-OK response code 408 Request Timeout. The cause is external transport failure, not a client bug, and unlike the auth-secret fetches in the same file this path uses a bare ctx.spawn with no retry, so every timeout becomes its own event.

Per .agents/skills/logging-and-error-reporting/SKILL.md, an external failure the app proceeds through belongs at log::warn! (breadcrumb only), not report_error!. This PR makes that one-line demotion and keeps the full error chain in the log line via {e:#}.

  • Fallback to the cached / default harness list is unchanged.
  • No new data is logged, so no secrets or PII are introduced.
  • The warp_errors::report_error import stays: the other call sites in this file (auth-secret fetch/create/delete) still use it and are out of scope.

Deliberately out of scope: triage also flagged that GraphQLError (crates/graphql/src/client.rs) is not register_error!'d and has no ErrorExt::is_actionable, so 408/429/5xx bypass the non-actionable classification for other report_error! sinks too. Registering it would change Sentry classification globally for every GraphQL call site — a much wider observability change than this XS ticket, and one worth its own review. It is intentionally left for a follow-up rather than folded in here.

Linked Issue

APP-5168 (triage-done; spec skipped as an obvious fix)

Testing

No regression test — testing-exempt (observability-only change). The diff changes which sink a failure is reported to; there is no behavioral logic to assert. A test could only re-state that this call site calls log::warn! rather than report_error!, which is tautological. This matches the precedent for the identical demotion in #14289 (next-command suggestion), which also shipped without a test.

Checks run locally, scoped to the touched crate (full-suite CI on this PR is the backstop):

  • ./script/format --check — passed.
  • cargo clippy -p warp --lib -- -D warnings — passed, 0 warnings.
  • cargo clippy -p warp --all-targets --tests -- -D warnings — passed, 0 warnings.
  • cargo nextest run -p warp --no-fail-fast — 6151 tests: 6148 passed, 3 failed, 7 skipped. All 3 failures are pre-existing and environmental, not caused by this change: I re-ran exactly those 3 against unmodified master (git checkout origin/master -- app/src/ai/harness_availability.rs) and got 3 tests run: 0 passed, 3 failed. They are server::server_api::ai::tests::ambient_agent_headers_for_task_overrides_existing_cloud_agent_header (the nsc CLI returns access denied in this sandbox), terminal::input::tests::test_histignorespace_support_in_zsh, and terminal::input::decorations::tests::test_decorations_with_multibyte_chars (syntax-highlight styling differs without bundled assets). None touch the changed code path.

Before → after on the real path: a failed get_available_harnesses (e.g. HTTP 408) previously produced a Sentry event plus an Error-level line; it now produces a Warn-level breadcrumb line Failed to fetch available harnesses: <error chain> and no Sentry event, with the cached/default harness list still in use.

No UI surface changes, so no visual proof applies (headless logging change).

Originating thread: https://warpdev.slack.com/archives/C0BDQDW8V5E/p1785869638922449

`HarnessAvailabilityModel::refresh` is a best-effort background refresh:
on failure the model keeps the cached (or default) harness list and the UI
stays usable. Its error arm nonetheless called `report_error!`, which is
reserved for actionable defects, so every transient transport failure
became a Sentry issue — ~275k events / ~112k users, dominated by
`HttpError: received non-OK response code 408 Request Timeout`.

Per the repo's logging-and-error-reporting guidance, an external failure the
app proceeds through belongs at `log::warn!`, so log the error chain locally
instead of capturing a Sentry event. Fallback behavior is unchanged.

Co-Authored-By: Warp <agent@warp.dev>
@cla-bot cla-bot Bot added the cla-signed label Aug 4, 2026
@warp-agent-staging warp-agent-staging Bot added the warpy-factory Label associated to the "Wob the Wuilder" factory on staging, also known as Warpy Factory. label Aug 4, 2026
@warp-agent-staging
warp-agent-staging Bot requested a review from acarl005 August 4, 2026 19:18
@warp-agent-staging
warp-agent-staging Bot marked this pull request as ready for review August 4, 2026 19:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed warpy-factory Label associated to the "Wob the Wuilder" factory on staging, also known as Warpy Factory.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant