Skip to content

feat(registry): surface legacy registry format with targeted UI#2229

Merged
peppescg merged 2 commits into
mainfrom
worktree-issue-2228-registry-legacy-format
May 12, 2026
Merged

feat(registry): surface legacy registry format with targeted UI#2229
peppescg merged 2 commits into
mainfrom
worktree-issue-2228-registry-legacy-format

Conversation

@peppescg
Copy link
Copy Markdown
Collaborator

@peppescg peppescg commented May 12, 2026

Summary

Screenshot 2026-05-12 at 14 12 52

When the configured custom registry serves data in the legacy ToolHive format, today the user sees the generic "Oops, something went wrong" error boundary even though the backend (stacklok/toolhive#5260) returns a structured HTTP 502 Bad Gateway with code: "registry_legacy_format". This PR wires the renderer to that contract so the user is redirected to Settings > Registry with a clear toast, just like the existing registry_auth_required / registry_unavailable flows.

Closes #2228
Depends on stacklok/toolhive#5260

Why this matters

Real-world report (#user-chat, May 12, 2026): after upgrading Studio to 0.34, the app failed to start because the previously-saved custom registry URL was returning legacy JSON. Recovery required CLI debugging and thv config unset-registry. The actionable hint is already in the API response — the renderer just needed to read it.

Changes

  • registry-errors-message.ts — new REGISTRY_LEGACY_FORMAT_CODE constant, isRegistryLegacyFormatError detector, REGISTRY_LEGACY_FORMAT_UI_MESSAGE + REGISTRY_LEGACY_FORMAT_TOAST_MESSAGE (no raw thv registry convert hint — desktop users should not see CLI commands), and an extension of getRegistryErrorToastMessage so the root beforeLoad guard already redirects to Settings on this code.
  • registry-error.tsx — third empty-state branch ("Unsupported registry format") for users who navigate directly to /registry while the source is misconfigured.
  • __tests__/registry-error.test.tsx — three new cases covering the legacy-format branch, including an explicit assertion that the raw CLI hint never reaches the visible UI.
  • __tests__/handle-registry-auth-redirect.test.ts — verifies the guard redirects to /settings?tab=registry with the legacy-format toast when the API returns the new code.

Test plan

  • pnpm run test:nonInteractive on the touched files — 23 tests pass
  • pnpm run type-check clean
  • pnpm run lint clean
  • Manual E2E against a backend serving legacy JSON: registry GET returns 502 + code: registry_legacy_format → Studio redirects to Settings > Registry with the toast, no error boundary

Reproducing locally

A backend in the failing state is needed. Until stacklok/toolhive#5260 merges:

```bash

Build backend from PR branch

cd && git checkout issues/5259
go build -o /tmp/thv-fix ./cmd/thv

Isolate config and point to a legacy JSON file

mkdir -p /tmp/thv-fix-test/toolhive
cat > /tmp/legacy-registry.json <<'JSON'
{"version":"1.0.0","servers":{"demo":{"image":"demo:latest","tier":"Community","transport":"stdio"}}}
JSON
cat > /tmp/thv-fix-test/toolhive/config.yaml <<'YAML'
secrets: { provider_type: "", setup_completed: false }
clients: { registered_clients: [] }
local_registry_path: /tmp/legacy-registry.json
YAML

Run backend

XDG_CONFIG_HOME=/tmp/thv-fix-test TOOLHIVE_SKIP_DESKTOP_CHECK=1 /tmp/thv-fix serve --port 8181

Run Studio dev from this worktree, attached to the backend

THV_PORT=8181 pnpm run start
```

To restore once verified:
```bash
curl -s -X PUT http://localhost:8181/api/v1beta/registry/default -H 'Content-Type: application/json' -d '{}'
```

🤖 Generated with Claude Code

The backend (stacklok/toolhive#5260) now returns a structured
HTTP 502 Bad Gateway with `code: "registry_legacy_format"` when the
configured custom registry serves data in the deprecated ToolHive format.
Without renderer-side handling the response was treated as a generic
fetch error and the user fell into the catch-all GenericError screen.

This change mirrors the existing `registry_auth_required` and
`registry_unavailable` plumbing:

- Add `isRegistryLegacyFormatError` detector plus the user-facing
  `REGISTRY_LEGACY_FORMAT_UI_MESSAGE` and toast copy (no raw CLI hint —
  desktop users should not see `thv registry convert`).
- Extend `getRegistryErrorToastMessage` so the root `beforeLoad` guard
  redirects to `/settings?tab=registry` with a persistent toast instead
  of letting the error reach `RootErrorComponent`.
- Add a third empty-state branch in `RegistryError` for users who
  navigate directly to `/registry` while the source is misconfigured.

Closes #2228

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 12, 2026 11:32
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the renderer to recognize the backend’s structured code: "registry_legacy_format" error and handle it with the same targeted redirect/toast UX used for other registry misconfiguration errors, avoiding the generic error boundary.

Changes:

  • Add detection and dedicated toast/UI copy for registry_legacy_format, and include it in the startup redirect guard toast mapping.
  • Add a dedicated “Unsupported registry format” empty-state branch on the Registry error page.
  • Extend unit tests to cover the new legacy-format redirect and ensure CLI hints from raw API messages are not displayed.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
renderer/src/routes/root/guards/tests/handle-registry-auth-redirect.test.ts Adds coverage that the guard redirects + stores the legacy-format toast when the API returns registry_legacy_format.
renderer/src/common/components/settings/registry/registry-errors-message.ts Introduces legacy-format error code detection and user-facing toast/UI messages, and wires it into getRegistryErrorToastMessage.
renderer/src/common/components/error/registry-error.tsx Adds a dedicated empty state for unsupported legacy registry format with Settings CTA.
renderer/src/common/components/error/tests/registry-error.test.tsx Adds tests for the legacy-format empty state and asserts raw CLI hints aren’t rendered.

@peppescg peppescg self-assigned this May 12, 2026
REGISTRY_LEGACY_FORMAT_UI_MESSAGE referred to the "upstream MCP format",
which is a CLI/protocol term that desktop users would not recognise.
Rephrase in plain language: the message now says to update the registry
source or reset to default, without naming the destination format.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@samuv samuv left a comment

Choose a reason for hiding this comment

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

🚀

@peppescg peppescg merged commit d103a63 into main May 12, 2026
17 checks passed
@peppescg peppescg deleted the worktree-issue-2228-registry-legacy-format branch May 12, 2026 12:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Surface legacy registry format error with a targeted UI flow

3 participants