Resolving the 409 "custom component library is being updated by someone else" error

What this error actually means

If you're syncing a custom component library (CCL) between Retool instances and see:

"The custom component library is being updated by someone else at this time"

This is misleading. It's a catch-all for any HTTP 409 from the CCL API. The most common real cause is a name conflict between two independently created libraries.

CCLs are not in Retool source control

CCLs aren't tracked by Retool's source control. Merging branches between dev and prod does NOT sync the CCL. Every time the CCL changes on dev, you need to run npx retool-ccl sync from your source to your target instance.

Note: The investigation steps below assume you have access to your Retool main storage Postgres database. This applies to self-hosted and MSH deployments. Retool Cloud users should contact support and reference this article.

Check 1: Is retool-ccl dev running concurrently?

If anyone is running retool-ccl dev against either instance while sync runs, that can produce a 409. Confirm no dev process is active before continuing.

Check 2: Was the CCL created independently on both instances?

This is the most common cause. Run this on each instance's main storage DB:

sql

SELECT * FROM custom_component_collections WHERE "organizationId" = <orgId>

Finding the org id: For self-hosted main admin spaces the orgId is usually 1, for spaces you need to run SELECT * FROM organizations to find the right orgId

If the UUIDs differ between instances but the names match, the libraries were created independently. This triggers the 409 as the underlying Postgres constraint on (organizationId, name) rejects the duplicate.

If UUIDs match on both sides and you still hit a 409, you're facing a less common revision-level conflict. Contact support in that case.

Resolving the name conflict

Once you've confirmed the UUIDs differ:

  1. On your target instance, go to /settings/custom-component-libraries
  2. Delete the conflicting CCL
  3. Re-run npx retool-ccl sync from source to target as outlined in the link above
  4. The sync now creates the library on the target with the source UUID

Important warning before you delete

Apps on the target instance that use this CCL reference the OLD target-side UUID. Deleting will cause broken components until those apps are updated with the new CCL.

To check which apps are affected:

  1. Find the target org id (see note above)
  2. Find the CCL UUID on the target:

sql

SELECT *
FROM custom_component_collections
WHERE "organizationId" = <org_id from above>
  1. Find apps whose latest page saves reference that CCL UUID:

sql

WITH latest_saves AS (
  SELECT DISTINCT ON (ps."pageId")
    ps."pageId", ps.data, ps."createdAt"
  FROM page_saves ps
  INNER JOIN pages p ON p.id = ps."pageId"
  WHERE p."organizationId" = <org_id from above>
  ORDER BY ps."pageId", ps."createdAt" DESC
)
SELECT ls."pageId", p.name AS app_name, ls."createdAt"
FROM latest_saves ls
JOIN pages p ON p.id = ls."pageId"
WHERE ls.data::text ILIKE '%<ccl uuid from point 2 above>%'
LIMIT 100;

SQL note: Search the bare UUID ('%<uuid>%'), not a scoped key like '%"collectionUuid":"<uuid>"%'. App state is stored as a JSON string inside a JSONB column, so inner quotes are escaped in data::text and a scoped match won't fire.

After deleting and re-syncing

Apps that referenced the deleted CCL UUID will need to be re-deployed from your source instance so they pick up the new shared UUID. Plan a maintenance window if any of these apps are business-critical.

3 Likes