Skip to content

fix(acp): allow custom model as default for non-local providers - #10438

Merged
michaelneale merged 1 commit into
aaif-goose:mainfrom
zelinewang:fix/10401-openrouter-custom-model-new-chat
Jul 18, 2026
Merged

fix(acp): allow custom model as default for non-local providers#10438
michaelneale merged 1 commit into
aaif-goose:mainfrom
zelinewang:fix/10401-openrouter-custom-model-new-chat

Conversation

@zelinewang

@zelinewang zelinewang commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Picking a custom OpenRouter model that isn't in the prefilled dropdown (e.g. google/gemini-3.5-flash) for a brand-new chat fails right away with RequestError: Invalid params. The same model works if you set it from inside an already-active chat, or from the CLI. It started in v1.41.0 and reproduces on Windows, macOS and Ubuntu (three reporters in #10401).

Root cause

When you pick a model for a new chat (no active session yet), the desktop saves it as the global default through the ACP defaults/save handler — on_defaults_save in crates/goose/src/acp/server/config.rs. That handler rejects any model that isn't already in the provider's inventory:

let model_exists = entry.default_model == model_id
    || entry.models.iter().any(|model| model.id == model_id)
    || (provider_id == "local" && local_inference_model_exists(model_id)?);
if !model_exists {
    return Err(agent_client_protocol::Error::invalid_params().data(format!(
        "Model '{model_id}' is not available for provider '{provider_id}'"
    )));
}

Error::invalid_params() is JSON-RPC -32602, which the desktop shows as RequestError: Invalid params. OpenRouter's inventory is a static, non-exhaustive 10-model list (OPENROUTER_KNOWN_MODELS, supports_refresh = false), so any custom model gets rejected — that's the same "10 seemingly random models" a commenter mentioned; the dropdown is that same static list.

The in-session path (set_session_config_optionapply_model_if_changed) and the CLI don't do this inventory check, which is why they still take custom models. The divergence only showed up in v1.41.0 because #10081 ("UI connect to ACP directly instead of goosed") routed the desktop's default-model save through this ACP handler; before that it went through goosed, which didn't validate.

The intended behavior was already set in #7255 ("remove allows_unlisted_models flag, always allow custom model entry") and #6761 ("enable custom model entry for OpenRouter provider"). The inventory check in on_defaults_save, added later by the provider-first onboarding work, ended up re-restricting what #7255 had opened up.

Fix

Only run the inventory check in on_defaults_save for the local provider, whose models can't be fetched on demand and so have to exist on disk or in the inventory. Every other provider allows custom/unlisted models, which matches the in-session and CLI paths. No behavior change for local, no new config.

Testing

  • Added test_custom_defaults_save_allows_unlisted_model in crates/goose/tests/acp_custom_requests_test.rs, following the existing test_custom_defaults_read / test_provider_switching_updates_session_state tests: it configures a provider and checks that saving a model that isn't in the inventory as the default now succeeds (it used to return Invalid params).
  • The local-provider check is untouched.
  • cargo test -p goose --test acp_custom_requests_test test_custom_defaults.

Related Issues

Fixes #10401. Restores the intended behavior from #7255 and #6761.

Selecting a custom/unlisted model for a brand-new chat saves it as the
default via the ACP defaults/save handler, which rejected any model
missing from the provider inventory with "Invalid params". OpenRouter's
inventory is a non-exhaustive 10-model static list, so custom models such
as google/gemini-3.5-flash failed on new chats once the desktop switched
to ACP in v1.41.0, even though the in-session and CLI paths still accept
them.

Restore the intended behavior (custom model entry is always allowed, see
aaif-goose#7255) by validating the model only for the local provider, whose models
cannot be fetched on demand.

Fixes aaif-goose#10401

@michaelneale michaelneale left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, this looks reasonable and makes it consistent with CLI

@michaelneale
michaelneale added this pull request to the merge queue Jul 18, 2026
Merged via the queue into aaif-goose:main with commit 445da5d Jul 18, 2026
22 checks passed
michaelneale added a commit that referenced this pull request Jul 20, 2026
* origin/main: (24 commits)
  fix(session): create inventory tables atomically with schema version (#10586)
  fix(providers): rewrite oneOf to anyOf in tool schemas for OpenAI-compatible backends (#10571)
  fix(evals): report cache-aware Harbor costs (#10430)
  fix(acp): allow custom model as default for non-local providers (#10438)
  fix(config): require absolute goose path roots (#10454)
  chore(deps): bump astral-sh/setup-uv from 8.2.0 to 8.3.2 (#10541)
  fix(permissions): scope smart approval by request (#10457)
  fix(summon): preserve fixed subrecipe values (#10452)
  chore(deps): bump websocket-driver from 0.7.4 to 0.7.5 in /documentation (#10506)
  fix(flatpak): bundle git so hermit can clone its package registry (#10511)
  feat(hooks): pass working_dir to the Stop hook context (#10296)
  chore(deps): bump actions/setup-java from 5.5.0 to 5.6.0 (#10540)
  chore(deps): bump actions/setup-node from 6 to 7 (#10539)
  chore(deps): bump EmbarkStudios/cargo-deny-action from 2.0.20 to 2.1.1 (#10542)
  chore(deps): bump gradle/actions/setup-gradle from 4.4.3 to 6.2.0 (#10543)
  Add declarative Sakana AI provider for the OpenAI-compatible Fugu API (#10357)
  fix(developer): expose AGENT_SESSION_ID to shell commands (#10428)
  Clean up stale documentation audit findings (#10114)
  Restore model interactions viewer (#10205)
  fix(acp): forward image content chunks to client during live session (#10485)
  ...

# Conflicts:
#	crates/goose/src/session/session_manager.rs
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.

RequestError: Invalid params, when setting custom OpenRouter model

2 participants