Skip to content

v1.1.1: defeat WP default-connector clobbering on Connectors page#24

Merged
superdav42 merged 1 commit intomainfrom
fix/connector-render-clobber
Apr 8, 2026
Merged

v1.1.1: defeat WP default-connector clobbering on Connectors page#24
superdav42 merged 1 commit intomainfrom
fix/connector-render-clobber

Conversation

@superdav42
Copy link
Copy Markdown
Contributor

@superdav42 superdav42 commented Apr 7, 2026

What

registerConnector() is now re-asserted on multiple ticks so the WP core registerDefaultConnectors() auto-register can't clobber our custom card with the generic API-key form.

Why

WP core's routes/connectors-home/content module runs registerDefaultConnectors() from inside an async dynamic import. By the time it executes, our top-level registerConnector() has already populated the connectors store. The store reducer in @wordpress/connectors spreads new config over the existing entry:

[ action.slug ]: {
    ...state.connectors[ action.slug ],   // existing
    slug: action.slug,
    ...action.config,                      // new (wins per key)
}

So the default's args.render = ApiKeyConnector overwrites our custom render. The user sees the generic API key form instead of the endpoint URL / model picker we built.

This is a real, observed regression — see the screenshot in #(linked issue) on the sister WebLLM connector plugin where exactly the same thing was happening.

Fix

Re-assert our registration on five ticks: sync, microtask, and setTimeout at 0/50/250/1000 ms. Whichever order the browser settles dynamic-import resolution in, we always end up last. Re-registering with the same render reference is idempotent so the redundant calls cost essentially nothing.

The proper upstream fix is WordPress/gutenberg#77116 (just opened, makes registerDefaultConnectors() skip slugs that already have a custom render). Once that ships in a Gutenberg release, this workaround can be removed.

Test plan

  • Activate this branch on a clean WordPress 7.0 install with @wordpress/ai plugin loaded.
  • Visit Settings → Connectors in a desktop browser.
  • Verify the "Compatible Endpoint" card shows the custom form (Endpoint URL / API Key / Model dropdown / Timeout) instead of the generic API Key field.
  • Verify the same on a fresh page load with no other plugins active that might affect script-module ordering — the previous behavior was that the bug appeared depending on which other connector plugins were enabled.

Release

Bumps version to 1.1.1 in:

  • ultimate-ai-connector-compatible-endpoints.php plugin header + ULTIMATE_AI_CONNECTOR_COMPATIBLE_ENDPOINTS_VERSION constant
  • package.json
  • readme.txt Stable tag + new changelog entry

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Fixed an issue where the connector could be overridden during WordPress initialization, ensuring the connector UI remains properly registered and visible to users.

WP core's routes/connectors-home/content.js runs registerDefaultConnectors()
from inside an async dynamic import. By the time it executes, our top-level
registerConnector() has already run, and the connectors store reducer
spreads new config over the existing entry — so the default's
`args.render = ApiKeyConnector` overwrites our custom card. The user sees
the generic API-key UI instead of the endpoint URL / model picker form.

The proper upstream fix is WordPress/gutenberg#77116. Until that lands and
ships in a Gutenberg release, work around it by re-asserting our
registration on five ticks (sync + microtask + setTimeout 0/50/250/1000ms)
so we always end up last regardless of dynamic-import resolution order.

Re-registration with the same render is idempotent so the redundant calls
cost almost nothing.

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

coderabbitai bot commented Apr 8, 2026

📝 Walkthrough

Walkthrough

This patch release (1.1.0 → 1.1.1) fixes connector registration persistence by re-asserting registerConnector() across multiple asynchronous scheduling ticks (immediate, microtask, and setTimeout at 0/50/250/1000ms) to prevent WordPress core's registerDefaultConnectors() from overriding the plugin's connector UI.

Changes

Cohort / File(s) Summary
Version Metadata
package.json, readme.txt, ultimate-ai-connector-compatible-endpoints.php
Version incremented from 1.1.0 to 1.1.1 across all manifests; changelog entry added documenting the registration re-assertion fix and its multi-tick timing strategy.
Connector Registration Logic
src/index.jsx
Replaced single immediate registerConnector() call with registerOurs() wrapper that re-invokes registration at immediate, microtask (Promise.resolve().then()), and multiple setTimeout intervals (0ms, 50ms, 250ms, 1000ms) to ensure persistence.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Hop hop, the connector registers with flair,
Through microtasks and timeouts everywhere,
At 0, then 50, then 250's sweet call,
A thousand ticks to ensure no fall,
WordPress core won't clobber us all!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main functional change: addressing a race condition where WordPress default connectors overwrite the plugin's custom connector, with a version bump to 1.1.1.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/connector-render-clobber

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/index.jsx (1)

425-430: Consider centralizing the retry delays.

A small delay list keeps the workaround easier to tune now and easier to remove once the upstream Gutenberg fix ships.

Small cleanup
 registerOurs();
 Promise.resolve().then( registerOurs );
-setTimeout( registerOurs, 0 );
-setTimeout( registerOurs, 50 );
-setTimeout( registerOurs, 250 );
-setTimeout( registerOurs, 1000 );
+[ 0, 50, 250, 1000 ].forEach( ( delay ) => {
+	setTimeout( registerOurs, delay );
+} );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/index.jsx` around lines 425 - 430, Centralize the retry delays used to
call registerOurs by replacing the multiple repeated calls with a single delays
array (e.g., const RETRY_DELAYS = [0, 50, 250, 1000]) plus the immediate
Promise.resolve().then(registerOurs) call; iterate over RETRY_DELAYS and call
setTimeout(registerOurs, delay) for each entry so future tuning or removal is
done in one place and the retry behavior is clearer; ensure you still call
registerOurs() once immediately and keep the
Promise.resolve().then(registerOurs) scheduling intact if needed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@ultimate-ai-connector-compatible-endpoints.php`:
- Line 24: Update the script registration to use the version constant instead of
the hard-coded '1.0.0': replace the literal version passed to
wp_register_script_module for the build/connector.js registration in
inc/admin.php with ULTIMATE_AI_CONNECTOR_COMPATIBLE_ENDPOINTS_VERSION so caches
are invalidated when the constant changes; ensure the call that registers the
connector script (wp_register_script_module for 'build/connector.js' or the
corresponding handle name) uses that constant for its $ver argument.

---

Nitpick comments:
In `@src/index.jsx`:
- Around line 425-430: Centralize the retry delays used to call registerOurs by
replacing the multiple repeated calls with a single delays array (e.g., const
RETRY_DELAYS = [0, 50, 250, 1000]) plus the immediate
Promise.resolve().then(registerOurs) call; iterate over RETRY_DELAYS and call
setTimeout(registerOurs, delay) for each entry so future tuning or removal is
done in one place and the retry behavior is clearer; ensure you still call
registerOurs() once immediately and keep the
Promise.resolve().then(registerOurs) scheduling intact if needed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4457d9cb-ffa8-4496-9ba9-08f253abd13a

📥 Commits

Reviewing files that changed from the base of the PR and between ebe7e42 and a19c13a.

📒 Files selected for processing (4)
  • package.json
  • readme.txt
  • src/index.jsx
  • ultimate-ai-connector-compatible-endpoints.php

}

define( 'ULTIMATE_AI_CONNECTOR_COMPATIBLE_ENDPOINTS_VERSION', '1.1.0' );
define( 'ULTIMATE_AI_CONNECTOR_COMPATIBLE_ENDPOINTS_VERSION', '1.1.1' );
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Use this version constant to invalidate the connector bundle.

inc/admin.php:14-32 still passes '1.0.0' to wp_register_script_module() for build/connector.js. That lets upgraded sites keep a cached pre-1.1.1 bundle, so the new re-registration logic may never run and the generic API-key card can still appear until caches expire.

Suggested change in inc/admin.php
-		'1.0.0'
+		ULTIMATE_AI_CONNECTOR_COMPATIBLE_ENDPOINTS_VERSION
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ultimate-ai-connector-compatible-endpoints.php` at line 24, Update the script
registration to use the version constant instead of the hard-coded '1.0.0':
replace the literal version passed to wp_register_script_module for the
build/connector.js registration in inc/admin.php with
ULTIMATE_AI_CONNECTOR_COMPATIBLE_ENDPOINTS_VERSION so caches are invalidated
when the constant changes; ensure the call that registers the connector script
(wp_register_script_module for 'build/connector.js' or the corresponding handle
name) uses that constant for its $ver argument.

@superdav42 superdav42 merged commit d601f4b into main Apr 8, 2026
4 checks passed
@superdav42
Copy link
Copy Markdown
Contributor Author

What

registerConnector() is now re-asserted on multiple ticks so the WP core registerDefaultConnectors() auto-register can't clobber our custom card with the generic API-key form.

Why

WP core's routes/connectors-home/content module runs registerDefaultConnectors() from inside an async dynamic import. By the time it executes, our top-level registerConnector() has already populated the connectors store. The store reducer in @wordpress/connectors spreads new config over the existing entry:

[ action.slug ]: {
    ...state.connectors[ action.slug ],   // existing
    slug: action.slug,
    ...action.config,                      // new (wins per key)
}

So the default's args.render = ApiKeyConnector overwrites our custom render. The user sees the generic API key form instead of the endpoint URL / model picker we built.
This is a real, observed regression — see the screenshot in #(linked issue) on the sister WebLLM connector plugin where exactly the same thing was happening.

Fix

Re-assert our registration on five ticks: sync, microtask, and setTimeout at 0/50/250/1000 ms. Whichever order the browser settles dynamic-import resolution in, we always end up last. Re-registering with the same render reference is idempotent so the redundant calls cost essentially nothing.
The proper upstream fix is WordPress/gutenberg#77116 (just opened, makes registerDefaultConnectors() skip slugs that already have a custom render). Once that ships in a Gutenberg release, this workaround can be removed.

Test plan

  • Activate this branch on a clean WordPress 7.0 install with @wordpress/ai plugin loaded.
  • Visit Settings → Connectors in a desktop browser.
  • Verify the "Compatible Endpoint" card shows the custom form (Endpoint URL / API Key / Model dropdown / Timeout) instead of the generic API Key field.
  • Verify the same on a fresh page load with no other plugins active that might affect script-module ordering — the previous behavior was that the bug appeared depending on which other connector plugins were enabled.

Release

Bumps version to 1.1.1 in:

  • ultimate-ai-connector-compatible-endpoints.php plugin header + ULTIMATE_AI_CONNECTOR_COMPATIBLE_ENDPOINTS_VERSION constant
  • package.json
  • readme.txt Stable tag + new changelog entry
    🤖 Generated with Claude Code

Merged via PR #24 to main.
Merged by deterministic merge pass (pulse-wrapper.sh).

aidevops.sh v3.6.161 spent 6m on this as a headless bash routine.

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.

1 participant