Skip to content

fix(secret): treat ErrNotFound on keyring delete as already deleted - #1758

Merged
Dumbris merged 1 commit into
smart-mcp-proxy:mainfrom
rudycelekli:fix/keyring-delete-notfound-20261023-01
Oct 26, 2026
Merged

Dumbris merged 1 commit into
smart-mcp-proxy:mainfrom
rudycelekli:fix/keyring-delete-notfound-20261023-01

Conversation

@rudycelekli

Copy link
Copy Markdown
Contributor

Bug

KeyringProvider.Delete treats every error from keyring.Delete as a keyring failure, including keyring.ErrNotFound. When the entry was already removed outside mcpproxy (Keychain Access, security delete-generic-password, Seahorse, Credential Manager), it returns before removeFromRegistry, so the name stays in the registry and List keeps showing it. Every later delete hits the same error.

It also calls markUnavailable(), so for the rest of the process every keyring Store/Delete short-circuits with ErrKeyringUnavailable, even though the keyring just answered fine.

Trigger

  1. Store a secret foo through the UI or mcpproxy secrets set.
  2. Delete the mcpproxy/foo item in Keychain Access.
  3. Call DELETE /api/v1/secrets/foo. It returns 500 failed to delete secret foo from keyring: secret not found in keyring on every retry, foo stays listed, and further secret writes fail as "keyring unavailable".

Fix

Treat keyring.ErrNotFound from the delete as success: the keyring answered and the entry is already gone. So the provider is not marked unavailable and execution continues to removeFromRegistry. Other errors behave as before. IsAvailable already uses the same convention, where ErrNotFound means "available, no secret".

Test

TestKeyringProvider_Delete_AlreadyGoneCleansRegistry uses the existing withKeyringMocks seam, with Delete returning ErrNotFound. It asserts that Delete returns nil, the registry drops foo, List returns only bar, and the provider is not marked unavailable.

Commands run

  • CGO_ENABLED=0 go test -count=1 ./internal/secret: ok
  • With the fix reverted (git stash of keyring_provider.go), -run AlreadyGone fails with Delete of an already-removed secret: failed to delete secret foo from keyring: secret not found in keyring.
  • gofmt -l on the edited files: no output

@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 0% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/secret/keyring_provider.go 0.00% 0 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@Dumbris Dumbris left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Verified: the PR test fails on main for the reason described and passes on this branch merged with main; race tests for the touched packages and CI lint (bare and server tags) are clean. Also built and tested together with the rest of this batch, independently reviewed, and cross-reviewed with a second model.

@Dumbris
Dumbris merged commit a5c2b1a into smart-mcp-proxy:main Oct 26, 2026
46 checks passed
@Dumbris

Dumbris commented Oct 26, 2026

Copy link
Copy Markdown
Member

Merged. Thank you, @rudycelekli! Deleting a secret that was already removed from the keyring no longer fails forever or marks the keyring unavailable.

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.

3 participants