#65867 closed defect (bug) (duplicate)
Connectors: AI provider API keys are re-validated on every settings update (/wp/v2/settings), causing needless provider calls and key resets
| Reported by: | hbhalodia | Owned by: | gziolo |
|---|---|---|---|
| Priority: | normal | Milestone: | |
| Component: | AI | Version: | |
| Severity: | normal | Keywords: | has-patch needs-testing |
| Cc: | Focuses: |
Description
Since the Connectors feature landed in 7.0, every POST/PUT to /wp/v2/settings re-validates all stored AI provider API keys — not just the key(s) actually being saved. Because validation is a live call to the provider, any settings save (including unrelated plugin settings that use this endpoint) triggers one network round-trip per stored AI key. If a stored key fails validation at that moment (e.g. the provider is unreachable or rate-limited), the key is silently reset to an empty string.
Details
_wp_connectors_rest_settings_dispatch() is hooked on rest_post_dispatch and runs on every /wp/v2/settings response:
add_filter( 'rest_post_dispatch', '_wp_connectors_rest_settings_dispatch', 10, 3 );
On an update it iterates every connector and validates each AI-provider key found in the response data:
$is_update = 'POST' === $request->get_method() || 'PUT' === $request->get_method(); foreach ( wp_get_connectors() as $connector_id => $connector_data ) { ... $value = $data[ $setting_name ]; // $data = $response->get_data() = the FULL settings object if ( $is_update && is_string( $value ) && '' !== $value && 'ai_provider' === $connector_data['type'] ) { if ( true !== _wp_connectors_is_ai_api_key_valid( $value, $connector_id ) ) { update_option( $setting_name, '' ); $data[ $setting_name ] = ''; continue; } } ... }
Two problems:
$datais the response of the settings controller, i.e. the entire settings object — every registered setting with its current stored value, not just the fields the client submitted. So the loop sees every connector's stored*_api_keyand revalidates it.- The guard is only
$is_update && non-empty && ai_provider; it never checks whether that particular key was part of the incoming request body.
_wp_connectors_is_ai_api_key_valid() performs a live provider call ($registry->isProviderConfigured( $provider_id ) after setting the key), so each revalidation is a network request.
Source: _wp_connectors_rest_settings_dispatch() and _wp_connectors_is_ai_api_key_valid() in Source
Steps to reproduce
- On a site with Connectors and an AI provider plugin active, configure and save a valid AI provider API key.
- Make any POST/PUT to
/wp/v2/settingsthat does not include that key — e.g. change the Site Title, or save an unrelated plugin's settings through the same endpoint. - Observe that Core revalidates the stored AI key (a provider network call fires).
- If that validation returns anything other than
true(provider down, rate limited, transient error), the stored key is overwritten with an empty string, even though it was never submitted.
Impact
- Unnecessary provider network calls and added latency on every settings save.
- Affects any plugin that saves settings via
/wp/v2/settings(e.g. the AI plugin). - Potential data loss: a valid-but-temporarily-unverifiable key can be wiped by an unrelated save.
Proposed fix
Only validate keys that were actually included in the current request payload, rather than every setting present in the response. For example, gate on the submitted params:
$submitted = (array) $request->get_json_params(); if ( $is_update && array_key_exists( $setting_name, $submitted ) && is_string( $value ) && '' !== $value && 'ai_provider' === $connector_data['type'] ) { // validate only keys the client actually sent }
Masking of keys in the response should continue to apply to all settings as before; only the validate-and-revert behavior should be scoped to submitted keys.
References
- Reproduced in the AI plugin: Reference
AI Usage
- Claude Code, Opus 5. Used for drafting ticket description and review the code for settings save.
Change History (11)
This ticket was mentioned in PR #13031 on WordPress/wordpress-develop by @hbhalodia.
4 weeks ago
#1
- Keywords has-patch added
#2
@
4 weeks ago
Pinging @jeffpaul and @dkotter for the ticket review and acceptance and then we can take this forward.
#4
@
3 weeks ago
Hi @jeffpaul, Let's work on this and plan to release it for the 7.2 may be? So that the unwanted settings changes does not wipe out the authentication keys from the settings.
Thanks,
@JeffPaul commented on PR #13031:
3 weeks ago
#5
@gziolo @jorgefilipecosta for your review in hopes of fixing as part of the 7.2 release cycle
#8
@
3 weeks ago
- Milestone 7.2
- Resolution → duplicate
- Status reviewing → closed
Duplicate of #65554.
@gziolo commented on PR #13031:
3 weeks ago
#9
Thanks for working on this. I noticed that PR #12350, opened earlier for Trac #65554, appears to address the same underlying issue: AI provider API keys should only be validated when they were submitted in the current /wp/v2/settings request.
The regression coverage added here to the existing connectors test suite is valuable and could be carried over to #12350. Could we reconcile the two implementations and continue with one PR to avoid maintaining duplicate fixes?
@hbhalodia commented on PR #13031:
2 weeks ago
#10
Thanks for working on this. I noticed that PR #12350, opened earlier for Trac #65554, appears to address the same underlying issue: AI provider API keys should only be validated when they were submitted in the current
/wp/v2/settingsrequest.
The regression coverage added here to the existing connectors test suite is valuable and could be carried over to #12350. Could we reconcile the two implementations and continue with one PR to avoid maintaining duplicate fixes?
Thanks @gziolo, I overlooked and thinked that the issue was not created, hence gone ahead and created the new ticket. Sorry for that.
For the PRs, yes we should accomodate it to the single PR. I would ask PR author if the changes can be ported over to it, so that I can close this and work on the new one.
Unfortunately, I do not have sufficient permission to update directly to that PR.
Cc: @itzmekhokan
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)
Trac ticket: https://core.trac.wordpress.org/ticket/65867
## Description
wp/v2/settings.## Use of AI Tools