Skip to content

Create-agent form resets provider config_schema fields to defaults on every keystroke #3216

Description

@IceRhymers

Summary

In the create-agent flow, any provider that advertises a config_schema has its config fields reset to their schema defaults (or wiped to empty) on every keystroke. Typing into a field like Inference auth snaps the value back almost immediately, making it effectively impossible to enter a non-default value through the UI.

Against a fast local provider binary the reset appears instantaneous, so it looks like the field refuses to accept input.

Impact

  • Any backend provider advertising config_schema fields is unconfigurable from Buzz Desktop.
  • Fields with a default snap back to that default; fields without one get wiped to empty.
  • Concrete case: I hit this while building a backend provider that runs agents on a Databricks sandbox / Lakebox. It advertises profile, inference_auth (default env), and idle_timeout. Its opt-in inference_auth: "sandbox" path cannot be selected from the UI at all — inference_auth always resets to env. (Details in feat(zero-token): opt-in inference_auth: "sandbox" — zero-Databricks-token inference via the baked per-user cfg IceRhymers/buzz-lakebox#11.)
  • There is no provider-side workaround: dropping the default from the schema only changes the reset target from env to empty.

Root cause

desktop/src/features/agents/ui/WhereToRunSection.tsx

  1. The probe useEffect (line 29) lists the entire draft in its dependency array:

    }, [draft, isProviderMode, onDraftChange, selectedBackendProvider]);  // line 64
  2. Every keystroke in ProviderConfigFields calls onDraftChange({ ...draft, providerConfig }) (lines 116–117), producing a new draft object — which re-triggers the effect and re-runs probeBackendProvider(...).

  3. When the probe resolves, it rebuilds defaults from config_schema and calls (lines 50–54):

    onDraftChange({
      ...draft,
      probedProvider: result,
      providerConfig: defaults,   // clobbers whatever the user just typed
    });

    So each keystroke fires a fresh probe, and each resolved probe overwrites providerConfig back to the schema defaults. This is both a correctness bug (typed values lost) and a churn bug (one provider probe per keystroke).

Proposed fix

Don't re-probe once the provider has already been probed:

React.useEffect(() => {
  if (!isProviderMode || !selectedBackendProvider) {
    setProbeError(null);
    return;
  }
  if (draft.probedProvider) return; // already probed; don't clobber user edits
  // ... existing probe logic
}, [draft, isProviderMode, onDraftChange, selectedBackendProvider]);

This stays correct on provider switches: the "Run on" <select> resets the draft to emptyWhereToRunDraft (probedProvider: null, lines 78–83), so a fresh probe still fires when the user picks a different provider.

Belt-and-suspenders — seed defaults without overwriting typed values, so a late-resolving probe can never erase user input:

providerConfig: { ...defaults, ...draft.providerConfig },

The early-return guard alone fixes both the reset and the probe-per-keystroke churn; the merge is defense-in-depth.

Repro

  1. Have any backend provider installed that advertises a config_schema with at least one property that has a default.
  2. Open the create-agent form, set Run on to that provider.
  3. Try to type a value into one of the config fields that differs from its default.
  4. Observed: the field snaps back to its default almost immediately (near-instant against a fast local provider binary).
  5. Expected: the typed value persists.

Discovered while building a backend provider that launches agents on a Databricks sandbox / Lakebox. Its inference_auth field (default env) could not be switched to sandbox from the UI. Details in IceRhymers/buzz-lakebox#11.

Screen.Recording.2026-07-27.at.2.53.09.PM.mov

Environment

  • Verified in block/buzz at main (component unchanged from 8bb43d51 through 3faea98).
  • File: desktop/src/features/agents/ui/WhereToRunSection.tsx

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions