Skip to content

Custom provider create fails with bare "invalid params": sdk/schema drifted from pinned goose commit after #331 #333

Description

@lumitor2

Before filing

Note on the release checkbox: not applicable in the usual sense — this is a
build-process/CI gap on main between releases, not a runtime behavior bug in
a shipped app. I have not checked whether a specific tagged release currently
has the same drift; see "Closest existing issue" below for why I think the
underlying gap (no check tying sdk/schema/*.json to goose-backend.lock.json)
is still open regardless.

Closest existing issue

none found

What's broken

Adding a Custom Provider (Settings → Add model provider → Custom) fails with a
bare "invalid params" toast that names no field, on a completely fresh main
checkout built with just setup && just dev. Root cause: sdk/schema/*.json
(and the generated TS client built from it) had drifted from the actual
pinned Goose backend's ACP schema, so requests using a newly-added required
field fail raw JSON-RPC param deserialization before any of the backend's own
(much more specific) validation ever runs.

Steps to reproduce

  1. Launch Berd (fresh main checkout, just setup && just dev).
  2. Settings → Add model provider → Custom.
  3. Fill in Display name, API URL, API key, and at least one model (all
    required fields satisfied per CustomProviderForm's own validation).
  4. Click Save/Add.

What you expected to happen

The custom provider is created (or a specific, actionable validation error is
shown, per the documented mapping in
distro/skills/berd-help/references/ai-providers.md).

What actually happened

A generic invalid params error, with no field name or other detail —
because the request fails at JSON-RPC param deserialization, before it ever
reaches normalize_custom_provider_upsert in
crates/goose/src/acp/server/providers.rs (the function that produces the
specific, .data()-annotated error messages this codebase otherwise relies
on for diagnosability).

Confirmed root cause by diffing the checked-in sdk/schema/acp-schema.json
against the schema generated fresh from the pinned commit
(2c02ed6fcf6a91b435aacfd5d02d713db8862153, per goose-backend.lock.json)
via scripts/regenerate-sdk-schema.sh: the pinned backend's
_goose/unstable/providers/custom/create (and /update) now requires a
toolshim: boolean field that the checked-in schema — and therefore
sdk/src/generated/types.gen.ts — never declared, so the frontend could never
send it.

Traced this back to #331 ("chore: bump goose backend pin to 2c02ed6f"), which
touches only goose-backend.lock.json (2 lines) and does not run
scripts/regenerate-sdk-schema.sh. That's the process gap: nothing (CI or
otherwise) verifies that sdk/schema/*.json still matches the pinned Goose
commit after a lockfile-only bump, so schema drift between the two can ship
silently until something exercises the specific new/changed field — in this
case months after #330's earlier pin bump had already gone in without
apparent issue, since it happened not to touch a field any existing frontend
call site used.

Once regenerated, the wider schema diff (not just toolshim) turned out to
also have changed GooseToolCallRequestUnstable: name used to be an
extensionName__toolName combined string, now it's a separate
required extensionName plus a bare name. That call site
(src/features/chat/ui/McpAppView.tsx, nested MCP-app tool calls) had not
been updated either, so it would have silently sent malformed tool-call
requests until the schema was brought current — same drift, different
symptom, likely from the same or a similarly unregenerated earlier pin bump.

How often does it happen?

Every time — reliably reproducible (with the currently-drifted schema; fixed
locally by regenerating it, see below).

Berd version

0.6.4 (main @ 67e02791, i.e. one commit after ce48ca5 / #331, dev build via
just dev)

Operating system

macOS (Apple Silicon)

Model and provider

n/a — failure is in provider configuration, before any model call

Relevant log output

[vite] (client) [console.warn] Failed to list custom providers: ...
    (unrelated console.warn on the providers settings page mount, from a
    separate GooseUnstableProvidersList call — noted here only because it
    fired around the same session and could otherwise look related; the
    actual create failure is a toast in the Add Custom Provider dialog that
    the renderer does not additionally log to the file logger, so I don't
    have a raw JSON-RPC error frame to paste — writing "unknown" rather than
    reconstructing one.)

Screenshots, recordings, or other context

Fix I applied locally (happy to open a PR if that changes given the
no-outside-PRs policy, otherwise treating this purely as a report):

  1. Ran scripts/regenerate-sdk-schema.sh (needed GOOSE_DEV_ALLOW_DIRTY=1
    and a one-line crates/goose/Cargo.toml fix in the vendored checkout —
    process-wrap's process-session feature isn't enabled on that crate's
    own Cargo.toml, only transitively via goose-mcp when built together
    with goose-cli, so building -p goose --bin generate-acp-schema alone
    fails to compile crates/goose/src/agents/platform_extensions/developer/shell.rs;
    probably worth its own upstream issue in aaif-goose/goose, filing there
    isn't mine to do from here).
  2. Added toolshim: false at both call sites building a
    CustomProviderCreateRequestUnstable/CustomProviderUpsertRequest
    (src/features/providers/lib/customProviderDraft.ts,
    src/features/providers/api/customProviders.ts) — no UI/config surface
    for tool-call shimming exists yet, so this is a default, not a real
    answer to "what should this value be."
  3. Fixed src/features/chat/ui/McpAppView.tsx's GooseUnstableToolsCall
    call to send extensionName + bare name instead of the old combined
    string.
  4. Updated the test fixtures that also needed the new required field.

Possible actual fix for the underlying gap: have CI regenerate
sdk/schema/*.json from the pinned commit and fail if it diffs from what's
checked in, so a lockfile-only bump can't silently drift from the schema it's
supposed to match.

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions