Skip to content

[Bug]: "The provider could not start this turn" drops the underlying error, and server traces rotate out within about an hour #20828

Closed as not planned

Description

@SwiggitySwerve

Before submitting

Area

apps/server (also packages/provider-core/src/server/failure.ts)

Steps to reproduce

  1. Let a provider turn fail at start with a ProviderAdapterTurnStartError whose cause is an ordinary adapter or SDK error, not one of the special-cased tags. Here this happened with a Cursor run whose run.start was never acknowledged, and with a restart continuation right after an auto-update.
  2. Open the failed run in the thread, or read its error turn item from statev2.sqlite.
  3. Follow the message's advice and check the server logs an hour or more later.

Expected behavior

The failure record keeps enough of the underlying cause (error tag, message, code) to tell the failure kinds apart, redacted and length-bounded. Or the server logs still cover the failure when the user follows the "check the server logs" advice.

Actual behavior

The thread and the persisted turn item show only:

The provider could not start this turn. Retry the turn; if it keeps failing, check the provider setup and server logs.

The stored failure is {class: "provider_error", code: null, retryable: null}. Three cases:

  • Cursor, grok-4.7, 2026-10-15 (two runs). The provider protocol log shows an outgoing run.start at 05:54:48.303Z and again at 14:03:28.318Z. Neither is followed by run.started. The runs were marked failed 2-23 ms later.
  • Codex-driver instance, 2026-10-17 04:37:56Z. This was a restart continuation right after desktop.lifecycle.beforeQuitForUpdate. Its failure record has the same shape.

Where the information is lost:

  • causeMessage in packages/provider-core/src/server/failure.ts returns fixed text for ProviderAdapterTurnStartError and only special-cases ContextHandoffBudgetError, ContextHandoffDeliveryUncertainError and ClaudeBackgroundWorkBlocksQueryReplacementError. The nested adapter error's message and code are not saved on the turn item.
  • server.trace.ndjson keeps 10 files of about 10 MB each. On this machine that covered about 45 minutes, so by the time anyone investigated, the spans for these failures had been rotated out.

The result is that authentication problems, an active run, the SDK rejecting the request, and restart races all look identical, and the user can only retry blindly.

Impact

Major degradation or frequent failure

Version or commit

0.1.1-nightly.20261017.3238 (relevant code unchanged on main @ 2993dfc)

Environment

Windows x64, desktop Nightly. Cursor provider (grok-4.7, Cursor SDK) and a custom Codex-driver instance (OpenAI-compatible proxy).

Logs or stack traces

# Cursor provider protocol log, 2026-10-15
[05:54:48.303Z] outgoing run.start   (no run.started follows; run failed at 05:54:48.326Z)
[14:03:28.318Z] outgoing run.start   (no run.started follows; run failed at 14:03:28.320Z)

# persisted error turn item, all three runs
{"class":"provider_error","message":"The provider could not start this turn. Retry the turn; if it keeps failing, check the provider setup and server logs.","code":null,"retryable":null}

Workaround

None for diagnosis. Retrying sometimes works. Copying the logs off the machine within the rotation window is the only way to keep the cause.

Suggested direction

Keep a redacted, length-bounded copy of the nested cause on the failure record, for example a detail or code field. The boundedText and redaction helpers already in failure.ts would cover the redaction. Alternatively, keep start-failure spans out of the high-volume rotation.

Activity

  1. juliusmarminge commented on Oct 17, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.

    Thanks for the detailed write-up. We're treating this as a diagnosability enhancement, not a bug, so I'm closing it here. Please take the "keep a redacted nested cause on the failure record" idea to Ideas.

    Cause message. On main, makeProviderFailure in packages/provider-core/src/server/failure.ts maps ProviderAdapterTurnStartError to that fixed sentence on purpose: adapter text is kept out of the user-facing message. Open PR #16303 continues that approach. It adds typed reasons for specific causes (previous turn still active, unreadable attachment) rather than copying the adapter's message. Whether to store more detail on the turn item is a product call, and that belongs in Ideas.

    Trace rotation. You can configure this. The server reads T3CODE_TRACE_MAX_BYTES (default 10 MB per file) and T3CODE_TRACE_MAX_FILES (see apps/server/src/cli/config.ts and docs/operations/observability.md). Raise them to keep more history. #19430 (merged Oct 14, so it should already be in your build) cut the spans written per streamed event from about 9 to 2, so on a busy machine even 10 × 10 MB may not be enough and raising the limits is the way to go.

    The Cursor run.start calls that never got run.started are a separate problem. If they keep happening, please open a dedicated issue with the provider protocol log.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementRequested improvement or new capability.via-triageFiled through npx t3 triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions