Skip to content

fix(api): keep MCP client_id when saving masked OAuth credentials - #45211

Open
lazerg wants to merge 2 commits into
langgenius:mainfrom
lazerg:fix/issue-45210-mcp-masked-client-id
Open

lazerg wants to merge 2 commits into
langgenius:mainfrom
lazerg:fix/issue-45210-mcp-masked-client-id

Conversation

@lazerg

@lazerg lazerg commented Oct 31, 2026 •

Copy link
Copy Markdown

Important

  1. Make sure you have read our contribution guidelines
  2. Ensure there is an associated issue
  3. Use the correct syntax to link this PR: Fixes #<issue number>.

Summary

Fixes #45210

Editing an MCP server sends the masked client_id and client_secret back, and _merge_credentials_with_masked tried to restore them from the top level of the stored credentials. They actually live under client_information, so the lookup missed and the masked string got saved as the real client ID, which then broke re-authorization with "Client not found". It now reads them through retrieve_client_information(), which also decrypts a stored secret. When the resolved ID and secret match what is stored, the credentials are now left as they are, so a name-only edit no longer wipes the tokens and DCR metadata.

Screenshots

Before After
... ...

Checklist

  • This change requires a documentation update, included: Dify Document
  • I understand that this PR may be closed in case there was no previous discussion or issues. (This doesn't apply to typos!)
  • I've verified the change and added or updated tests where meaningful regression risk justifies coverage.
  • I've updated the documentation accordingly.
  • I ran make lint && make type-check (backend) and vp staged (frontend) to appease the lint gods

@lazerg
lazerg requested a review from QuantumGhost as a code owner October 31, 2026 17:30
@github-actions github-actions Bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Oct 31, 2026

@GYJ99 GYJ99 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for fixing the nested masked-credential lookup. I think the reported DCR → edit → re-authorize path still has an important regression to cover: update_provider() calls _process_credentials() whenever the edit payload includes authentication.client_id, and that method still unconditionally calls _build_and_encrypt_credentials(). The builder replaces the stored credential JSON with new client_information containing is_dynamic_registration: False, dropping the original dynamic-registration metadata and any existing access/refresh tokens. A name-only edit can therefore preserve the unmasked ID but still erase the active OAuth state and change the registration mode.

Could you add a regression at the update_provider() level asserting that a name-only edit with unchanged masked ID/secret preserves the existing DCR metadata and tokens, and avoid rebuilding credentials when the effective ID/secret are unchanged? I also see #45212 addressing the same Issue; coordinating a single fix would prevent overlapping changes. This is based on the current code paths, not a full runtime test.

@lazerg

lazerg commented Oct 31, 2026

Copy link
Copy Markdown
Author

Good catch, I added the update_provider test and now skip the rebuild when the ID and secret are unchanged, so tokens and DCR metadata stay intact (046cd47).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] MCP OAuth re-authorization fails ("Client not found") after modifying server parameters due to masked client_id

2 participants