Agent defaults: "Couldn't save." discards the backend validation message, making the failure undiagnosable

Open Beginner friendly
#4,568 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
82/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Quiet
Tech stack
rust, typescript
Domain
desktop

Research direction

Start in desktop/src/features/agents/ui/AgentDefaultsEditor.tsx around line 233 and inspect the error shape returned by the Tauri set_global_agent_config call. Reproduce the validation failure with a derived provider or model key in env_vars, then verify that the backend's validation message is shown instead of only "Couldn't save.".

Written by the indexing model from the issue text.

Description

Summary

AgentDefaultsEditor discards the backend's validation message and shows a bare "Couldn't save." The backend's reason is accurate and actionable — it just never reaches the user.

Result: a save that can never succeed, with no indication of why, anywhere. No app log, no relay log (even at DEBUG), no config file touched.

Reproduce

  1. Put a derived provider/model key into the global agent config's env_vars — e.g. GOOSE_PROVIDER or GOOSE_MODEL (easy to do if you have edited global-agent-config.json directly, e.g. as a workaround for a provider issue).
  2. Open Agents → Agent defaults, change the harness or model, press Save defaults.
  3. Every save fails with Couldn't save. and no further detail.

Cause

The backend correctly rejects it — desktop/src-tauri/src/managed_agents/global_config/mod.rs:113:

if !derived.is_empty() {
    return Err(format!(
        "the following keys must be set via the structured provider/model fields, \
         not as env vars: {}",
        derived.join(", ")
    ));
}

against DERIVED_PROVIDER_MODEL_ENV_KEYS (GOOSE_MODEL, GOOSE_PROVIDER, BUZZ_AGENT_MODEL, BUZZ_AGENT_PROVIDER).

The rule itself is right — Buzz derives those vars from the structured fields, so allowing both would create two sources of truth. The problem is purely that the message is thrown away in desktop/src/features/agents/ui/AgentDefaultsEditor.tsx:233:

} catch (err) {
  setSaveState("error");
  setSaveError(typeof err === "string" ? err : "Couldn't save.");
}

set_global_agent_config returns Result<GlobalAgentConfigSaveResult, String>, so the reason is a string on the Rust side — but whatever reaches the catch fails the typeof err === "string" test (Tauri appears to wrap it), so the fallback always wins.

Suggested fix

Unwrap the Tauri error rather than testing it as a bare string, e.g.:

const message =
  typeof err === "string" ? err :
  (err as { message?: string })?.message ?? "Couldn't save.";
setSaveError(message);

Even surfacing String(err) would be a large improvement over the current dead end.

Impact

The validation is a guard rail users are quite likely to hit — anyone who has hand-edited global-agent-config.json to work around a provider problem will land on it. As shipped, the only way to discover the cause is to read the Rust source.

Environment

  • Buzz Desktop 0.5.x, macOS arm64
  • Relay: self-hosted, built from source

Related

Same family as #3636 and #4278 — a correct signal produced internally, then discarded before it reaches the operator.

Dominant language
Rust
Stars
33.7k
Forks
4.4k
Avg merge
1d 21h
Merged PRs (30d)
239

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from block/buzz

All issues in block/buzz

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.