Skip to content

Bug: keyless org model resolution throws uncaught NoProviderAvailableError — expected "no AI provider configured yet" onboarding state recorded as error-level server events (8 events, 07-07→07-28, latent) #3129

Description

@larryro

Source: GlitchTip sweep of demo.tale.dev, 2026-09-02 (full 374-group pass over the project). Board task: TAL-28.

Prior art this is NOT a duplicate of: the closed #2576 (chat composer stays editable when no API key is configured) and #2375 ("No API key configured" toast should link to the provider settings) fixed the client UX; #3127 is the capability-mismatch flavor (completions-only model in chat) and open #2991 the embedding flavor. This issue is the remaining server-side flavor: the refusal itself is thrown as an uncaught plain error.

Evidence

  • TALE-PROJECT-P9Uncaught NoProviderAvailableError: No API key is configured for this organization yet. Open Settings → AI providers and add one to start chatting.8 events, 2026-07-07T12:43Z → 2026-07-28T02:12Z, error level. Latest event: func: providers/file_actions:resolveModelByTag (action, node runtime), authenticated user (…7584413p), server_name: tale_platform. (Raw per-event history has aged out of GlitchTip retention; group metadata re-verified via the API today.)
  • Timeline: the last events post-date the 2026-07-12 close of Bug: Chat composer stays editable when no API key is configured #2576 — the client-side composer gate did not (and cannot) stop server-side callers from resolving a model in a keyless org. The 07-28T02:12Z event sits in the nightly-automation window, consistent with agent/automation traffic reaching model resolution without a provider key.
  • Quiet since 07-28 — latent, not gone: every fresh org that reaches any model-resolution path (chat via API, automation run, agent schedule) before an admin configures a provider reproduces it.

Read

"Org has no AI provider key yet" is an expected onboarding state — the error text is literally a UI remediation string ("Open Settings → AI providers and add one to start chatting."). But resolveModelByTag throws it as a plain uncaught error, so each occurrence mints an error-level GlitchTip event: the same expected-state-surfaced-as-uncaught-server-error class as #3111 (approval conflict) and #3088's reporting-policy direction. The platform already owns the classification machinery: services/platform/lib/shared/chat-errors.ts defines the missing_api_key ChatErrorCode (i18n hint errorHintMissingApiKey) and the chat path encodes failures into a structured envelope — the resolution path just never issues a structured refusal.

Module note: convex/providers/file_actions.ts is private-overlay (absent from the public tree at HEAD; NoProviderAvailableError surfaces publicly only in lib/shared/chat-errors.ts + backend/core/tts/error_codes.ts classification tables) — the throw-site fix lands overlay-side, same situation as #3110/#3111.

Fix direction

  1. Structured refusal: resolveModelByTag (and sibling model-resolution entry points) throws ConvexError with a stable code (e.g. NO_PROVIDER_CONFIGURED), mapped to the existing missing_api_key classification so every caller (composer, automations, API) can branch on it instead of string-matching.
  2. Reporting policy: stop recording the expected flavor as an uncaught server error (align with Bug: expected "Unauthenticated" refusals land as uncaught server errors — ~550+ GlitchTip events across 12+ groups, still firing daily #3088 direction 3 / Bug: request_human_input crashes uncaught when an approval is already pending on the thread — expected conflict surfaced as a plain server Error (5 events, 08-07→08-12) #3111 item 3) — a keyless org resolving a model is a refusal, not a defect.
  3. Non-chat callers: verify automations/schedules/agent runs in a keyless org surface "configure a provider" to the org admin rather than failing runs opaquely — otherwise a scheduled automation in a keyless org retries into this forever (Bug: workflow-engine schedules retry permanently-misconfigured runs forever — 5,370 errors in 10 days from one issue-desk schedule, each reported twice #3092's permanently-misconfigured class).

Acceptance

  • Chat, automation, and API paths in a keyless org receive a structured NO_PROVIDER_CONFIGURED refusal; the client keeps its existing guidance UX; no uncaught NoProviderAvailableError server events.
  • TALE-PROJECT-P9 stays flat; exercising a fresh demo org before provider setup produces zero error-level events from model resolution.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions