Fix: plugin DS shows false unsaved state on default branch after git sync#16540
Merged
Conversation
…sync Encrypted fields are omitted from git serialization (credentials are never stored in git). After a pull, the DSVO is missing those keys. The save-state check compared state.options (missing encrypted keys) against normalizedSavedOptions (which fills missing keys from dsDefaults/manifest), producing a false mismatch on first open for plugin-type datasources. Fix: normalize state.options with dsDefaults using the same reduction before the deepEqual comparison, so both sides are symmetric.
Contributor
🚀 EE Pre-release Review App Deployed!
Deployed using DockerHub-based pipeline - Pre-release Edition |
… name sync !isGitEnabled skipped the isDefault DSV name update on the default git branch, leaving it stale after a rename. shouldUpdateDefault is already true for both the no-git case and default-branch renames, and false only for feature branches.
… unsaved state for plugin DSes
For new tj:version schema plugins (GitHub, OpenAI, Supabase, Plivo, etc.),
dsDefaults is empty so the prior reduce-based normalization was a no-op.
Encrypted fields stripped from git-synced DSVOs are absent from
normalizedSavedOptions while DynamicForm initializes them as { value: '' }
in state.options, producing a false mismatch on default branch open.
Fill missing encrypted schema fields from dataSourceMeta.options with
{ value: '' } on both sides. Resolve the active key form from
normalizedCurrentOptions first (DynamicForm may camelize schema keys,
e.g. auth_token → authToken) to avoid introducing duplicate snake/camel
keys that cause the opposite mismatch.
branchId presence already implies git is enabled — no need to query WorkspaceBranch a second time to derive isGitEnabled. Hoist isGitEnabled into the existing branchId branch (true by definition) and only hit the DB for the ambiguous !branchId case. Reduces WorkspaceBranch reads from two to one per update call when branchId is present.
Contributor
🔄 EE Pre-release Review App RebuildingNew commit Using cached layers for faster build |
…ataSource" This reverts commit ea2398d.
Contributor
🔄 EE Pre-release Review App RebuildingNew commit Using cached layers for faster build |
Contributor
🔄 EE Pre-release Review App RebuildingNew commit Using cached layers for faster build |
johnsoncherian
approved these changes
Jun 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Two fixes bundled together — both related to data source consistency in git-sync environments.
1. Plugin DS shows false unsaved state on default branch after git sync (frontend)
When a plugin-type data source is pulled from git, encrypted fields (credentials) are stripped from the git file during serialization — they're never stored in git. After a pull, the DSVO is missing those keys entirely.
The save-state check compared
state.options(missing encrypted keys) againstnormalizedSavedOptions(which fills missing keys fromdsDefaultsvia the plugin manifest), producing a false mismatch on first open — the DS appeared unsaved and triggered a blocking modal.Fix: normalize
state.optionswithdsDefaultsusing the same reduction before thedeepEqualcomparison, so both sides are symmetric and the initial diff is zero.2. Non-branch DS rename had no uniqueness check + isDefault DSV name was never synced (backend)
Before this PR, renaming a data source on the non-branch path (no git sync / license expired) had no uniqueness enforcement —
ensureUniqueActiveNameForUpdatewas only called inside the branch path. Additionally, renaming a DS updateddata_sources.namebut leftdata_source_versions.name(isDefault DSV) stale, causing drift between the two tables.Fix: added
ensureUniqueActiveNameForUpdateon the non-branch rename path, and sync the isDefault DSV name whenever a DS is renamed outside a branch context.Why no migrations
Existing duplicate names were already cleaned up by migration
1773229178900(ships before this PR). By the timeensureUniqueActiveNameForUpdateruns in production, the DB is already clean. No backfill needed — these changes enforce consistency going forward.Changes
frontend/src/modules/dataSources/components/DataSourceManager/DataSourceManager.jsx— normalizeoptionsstate withdsDefaultsbeforedeepEqualcomparisonserver/src/modules/data-sources/util.service.ts— uniqueness check + isDefault DSV name sync on non-branch rename path