Skip to content

Cursor provider: most live-catalog models fail with ERROR_BAD_MODEL_NAME (Unknown model ID) #1226

Description

@matheusmaais

Summary

Every Cursor model returned by the live picker except composer-* and bare gemini ids fails immediately with:

Cursor agent stream error: {"code":"not_found","details":[{"debug":{"details":{"analyticsMetadata":{"actionRequired":"config"},"detail":"Unknown model ID: cursor-grok-4.6-high-fast",...},"error":"ERROR_BAD_MODEL_NAME","isExpected":true},...}]}

Reproduce: jcode provider-doctor cursor --tier full --model cursor-grok-4.6-high-fast (or pick any grok/claude/gpt model from /model and send a message).

Root cause

jcode-provider-cursor-runtime's hand-rolled protobuf/HTTP2 transport (agent_transport.rs, talking directly to agent.v1.AgentService/Run on agentn.global.api5.cursor.sh) sends the composite catalog id (e.g. cursor-grok-4.6-high-fast, claude-opus-5-thinking-high, gpt-5.6-sol-xhigh) verbatim as the model name.

The real backend — the same one the official cursor-agent CLI talks to with the same API key — only accepts the bare base id (grok-4.6, claude-opus-5, gpt-5.6-sol), with effort/fast/thinking sent as separate parameters. This is visible directly in ~/.cursor/cli-config.json's modelParameters, which is keyed by the bare id.

I confirmed this by running cursor-agent --model cursor-grok-4.6-high-fast -p "..." (the official CLI) with the exact same CURSOR_API_KEY jcode was using — it worked fine — while jcode's transport failed on the identical model id.

Fix

I already wrote, tested, and verified the fix locally. resolve_model_id() in agent_transport.rs strips, in this order, before building the wire request:

  1. a leading cursor- vendor prefix
  2. a trailing -fast suffix (captured separately as the fast flag)
  3. trailing effort/mode suffixes (-xhigh, -high, -medium, -low, -thinking), which can stack (e.g. claude-opus-5-thinking-high → claude-opus-5)

Ids that don't match any pattern (composer-2.5, gemini-3.1-pro, sonnet-4.6) pass through unchanged.

Live verification (real Cursor account, real API key)

model id from the live catalog before after
cursor-grok-4.6-high-fast ERROR_BAD_MODEL_NAME chat reply OK
claude-opus-5-thinking-high ERROR_BAD_MODEL_NAME chat reply OK
claude-sonnet-5-thinking-high ERROR_BAD_MODEL_NAME chat reply OK
gpt-5.4-high ERROR_BAD_MODEL_NAME chat reply OK
gpt-5.6-sol-xhigh ERROR_BAD_MODEL_NAME chat reply OK
gemini-3.7-flash-high ERROR_BAD_MODEL_NAME chat reply OK
composer-2.5 (already bare) OK OK (unaffected)

jcode provider-doctor cursor --tier full on cursor-grok-4.6-high-fast went from failing at "Non-streaming chat completion" to passing chat + streaming.

Tests

Added 6 unit tests (resolve_model_id_*) covering every composite pattern observed in the live catalog, rebased cleanly onto current master, and all 21 tests in jcode-provider-cursor-runtime pass.

Patch

I can't open a PR directly (repo's PR creation is restricted to collaborators), but the branch is public on my fork: https://github.com/matheusmaais/jcode/tree/fix/cursor-composite-model-ids (1 commit, rebased on current master, diff attached below for convenience).

Full diff

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

    Labels

    autonomous: noNeeds your brain: a product/design decision is required before anyone acts.bugSomething isn't workingtriage: needs-decisionNeeds maintainer decision/design thought

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions