diff --git a/changelog/entries/unreleased/bug/3191_fix_data_sync_form_protected_fields.json b/changelog/entries/unreleased/bug/3191_fix_data_sync_form_protected_fields.json
new file mode 100644
index 000000000..01bc1e1ea
--- /dev/null
+++ b/changelog/entries/unreleased/bug/3191_fix_data_sync_form_protected_fields.json
@@ -0,0 +1,8 @@
+{
+  "type": "bug",
+  "message": "Fix protected fields in the data sync forms.",
+  "domain": "database",
+  "issue_number": 3191,
+  "bullet_points": [],
+  "created_at": "2025-02-27"
+}
diff --git a/enterprise/web-frontend/modules/baserow_enterprise/components/dataSync/GitHubIssuesDataSyncForm.vue b/enterprise/web-frontend/modules/baserow_enterprise/components/dataSync/GitHubIssuesDataSyncForm.vue
index b00d79efa..0df2623b2 100644
--- a/enterprise/web-frontend/modules/baserow_enterprise/components/dataSync/GitHubIssuesDataSyncForm.vue
+++ b/enterprise/web-frontend/modules/baserow_enterprise/components/dataSync/GitHubIssuesDataSyncForm.vue
@@ -47,16 +47,8 @@
       :helper-text="$t('githubIssuesDataSync.apiTokenHelper')"
       small-label
       :protected-edit="update"
-      @enabled-protected-edit="allowedValues.push('github_issues_api_token')"
-      @disable-protected-edit="
-        ;[
-          allowedValues.splice(
-            allowedValues.indexOf('github_issues_api_token'),
-            1
-          ),
-          delete values['github_issues_api_token'],
-        ]
-      "
+      @enabled-protected-edit="values.github_issues_api_token = ''"
+      @disable-protected-edit="values.github_issues_api_token = undefined"
     >
       <FormInput
         v-model="v$.values.github_issues_api_token.$model"
@@ -96,15 +88,16 @@ export default {
     return { v$: useVuelidate({ $lazy: true }) }
   },
   data() {
-    const allowedValues = ['github_issues_owner', 'github_issues_repo']
-    if (!this.update) {
-      allowedValues.push('github_issues_api_token')
-    }
     return {
-      allowedValues: ['github_issues_owner', 'github_issues_repo'],
+      allowedValues: [
+        'github_issues_owner',
+        'github_issues_repo',
+        'github_issues_api_token',
+      ],
       values: {
         github_issues_owner: '',
         github_issues_repo: '',
+        github_issues_api_token: this.update ? undefined : '',
       },
     }
   },
@@ -127,7 +120,7 @@ export default {
           required: helpers.withMessage(
             this.$t('error.requiredField'),
             requiredIf(() => {
-              return this.allowedValues.includes('github_issues_api_token')
+              return this.values.github_issues_api_token !== undefined
             })
           ),
         },
diff --git a/enterprise/web-frontend/modules/baserow_enterprise/components/dataSync/GitLabIssuesDataSyncForm.vue b/enterprise/web-frontend/modules/baserow_enterprise/components/dataSync/GitLabIssuesDataSyncForm.vue
index daef43dd6..ef0c6da8a 100644
--- a/enterprise/web-frontend/modules/baserow_enterprise/components/dataSync/GitLabIssuesDataSyncForm.vue
+++ b/enterprise/web-frontend/modules/baserow_enterprise/components/dataSync/GitLabIssuesDataSyncForm.vue
@@ -48,13 +48,8 @@
       :helper-text="$t('gitlabIssuesDataSync.accessTokenHelper')"
       small-label
       :protected-edit="update"
-      @enabled-protected-edit="allowedValues.push('gitlab_access_token')"
-      @disable-protected-edit="
-        ;[
-          allowedValues.splice(allowedValues.indexOf('gitlab_access_token'), 1),
-          delete values['gitlab_access_token'],
-        ]
-      "
+      @enabled-protected-edit="values.gitlab_access_token = ''"
+      @disable-protected-edit="values.gitlab_access_token = undefined"
     >
       <FormInput
         v-model="v$.values.gitlab_access_token.$model"
@@ -93,15 +88,17 @@ export default {
     return { v$: useVuelidate({ $lazy: true }) }
   },
   data() {
-    const allowedValues = ['gitlab_url', 'gitlab_project_id']
-    if (!this.update) {
-      allowedValues.push('gitlab_access_token')
-    }
+    const allowedValues = [
+      'gitlab_url',
+      'gitlab_project_id',
+      'gitlab_access_token',
+    ]
     return {
       allowedValues,
       values: {
         gitlab_url: 'https://gitlab.com',
         gitlab_project_id: '',
+        gitlab_access_token: this.update ? undefined : '',
       },
     }
   },
@@ -125,7 +122,7 @@ export default {
           required: helpers.withMessage(
             this.$t('error.requiredField'),
             requiredIf(() => {
-              return this.allowedValues.includes('gitlab_access_token')
+              return this.values.gitlab_access_token !== undefined
             })
           ),
         },
diff --git a/enterprise/web-frontend/modules/baserow_enterprise/components/dataSync/HubspotContactsDataSyncForm.vue b/enterprise/web-frontend/modules/baserow_enterprise/components/dataSync/HubspotContactsDataSyncForm.vue
index 184eafa81..129037cfa 100644
--- a/enterprise/web-frontend/modules/baserow_enterprise/components/dataSync/HubspotContactsDataSyncForm.vue
+++ b/enterprise/web-frontend/modules/baserow_enterprise/components/dataSync/HubspotContactsDataSyncForm.vue
@@ -8,6 +8,8 @@
       :helper-text="$t('hubspotContactsDataSync.accessTokenHelper')"
       :protected-edit="update"
       small-label
+      @enabled-protected-edit="values.hubspot_access_token = ''"
+      @disable-protected-edit="values.hubspot_access_token = undefined"
     >
       <FormInput
         v-model="v$.values.hubspot_access_token.$model"
@@ -49,7 +51,7 @@ export default {
     return {
       allowedValues: ['hubspot_access_token'],
       values: {
-        hubspot_access_token: '',
+        hubspot_access_token: this.update ? undefined : '',
       },
     }
   },
diff --git a/enterprise/web-frontend/modules/baserow_enterprise/components/dataSync/JiraIssuesDataSyncForm.vue b/enterprise/web-frontend/modules/baserow_enterprise/components/dataSync/JiraIssuesDataSyncForm.vue
index d6e4c6393..3553caac3 100644
--- a/enterprise/web-frontend/modules/baserow_enterprise/components/dataSync/JiraIssuesDataSyncForm.vue
+++ b/enterprise/web-frontend/modules/baserow_enterprise/components/dataSync/JiraIssuesDataSyncForm.vue
@@ -49,13 +49,8 @@
       small-label
       class="margin-bottom-2"
       :protected-edit="update"
-      @enabled-protected-edit="allowedValues.push('jira_api_token')"
-      @disable-protected-edit="
-        ;[
-          allowedValues.splice(allowedValues.indexOf('jira_api_token'), 1),
-          delete values['jira_api_token'],
-        ]
-      "
+      @enabled-protected-edit="values.jira_api_token = ''"
+      @disable-protected-edit="values.jira_api_token = undefined"
     >
       <template #label>{{ $t('jiraIssuesDataSync.apiToken') }}</template>
       <FormInput
@@ -111,17 +106,19 @@ export default {
     return { v$: useVuelidate({ $lazy: true }) }
   },
   data() {
-    const allowedValues = ['jira_url', 'jira_username', 'jira_project_key']
-    if (!this.update) {
-      allowedValues.push('jira_api_token')
-    }
+    const allowedValues = [
+      'jira_url',
+      'jira_username',
+      'jira_project_key',
+      'jira_api_token',
+    ]
     return {
       allowedValues,
       values: {
         jira_url: '',
         jira_username: '',
         jira_project_key: '',
-        jira_api_token: '',
+        jira_api_token: this.update ? undefined : '',
       },
     }
   },
@@ -145,7 +142,7 @@ export default {
           required: helpers.withMessage(
             this.$t('error.requiredField'),
             requiredIf(() => {
-              return this.allowedValues.includes('gitlab_access_token')
+              return this.values.jira_api_token !== undefined
             })
           ),
         },
diff --git a/web-frontend/modules/database/components/dataSync/ConfigureDataSyncSettings.vue b/web-frontend/modules/database/components/dataSync/ConfigureDataSyncSettings.vue
index af171fd66..d77a69662 100644
--- a/web-frontend/modules/database/components/dataSync/ConfigureDataSyncSettings.vue
+++ b/web-frontend/modules/database/components/dataSync/ConfigureDataSyncSettings.vue
@@ -118,7 +118,13 @@ export default {
       }
     },
     async submitted(values) {
-      await this.update(this.table, values, this.syncTableValue)
+      // Remove the `undefined` values, because those contain not updated secrets that
+      // are only meant to be included in the update request if they've changed
+      // because they're not exposed by the backend.
+      const valuesWithoutUndefined = Object.fromEntries(
+        Object.entries(values).filter(([_, v]) => v !== undefined)
+      )
+      await this.update(this.table, valuesWithoutUndefined, this.syncTableValue)
       if (!this.syncTableValue) {
         this.completed = true
       }
diff --git a/web-frontend/modules/database/components/dataSync/PostgreSQLDataSync.vue b/web-frontend/modules/database/components/dataSync/PostgreSQLDataSync.vue
index b2c52a7b9..20d74334b 100644
--- a/web-frontend/modules/database/components/dataSync/PostgreSQLDataSync.vue
+++ b/web-frontend/modules/database/components/dataSync/PostgreSQLDataSync.vue
@@ -35,13 +35,8 @@
       small-label
       :protected-edit="update && field.protectedEdit"
       class="margin-bottom-2"
-      @enabled-protected-edit="allowedValues.push(field.name)"
-      @disable-protected-edit="
-        ;[
-          allowedValues.splice(allowedValues.indexOf(field.name), 1),
-          delete values[field.name],
-        ]
-      "
+      @enabled-protected-edit="values.postgresql_password = ''"
+      @disable-protected-edit="values.postgresql_password = undefined"
     >
       <template #label>{{
         $t(`postgreSQLDataSync.${field.translationPrefix}`)
@@ -129,13 +124,11 @@ export default {
       'postgresql_username',
       'postgresql_port',
       'postgresql_database',
+      'postgresql_password',
       'postgresql_schema',
       'postgresql_table',
       'postgresql_sslmode',
     ]
-    if (!this.update) {
-      allowedValues.push('postgresql_password')
-    }
     return {
       allowedValues,
       values: {
@@ -143,6 +136,9 @@ export default {
         postgresql_username: '',
         postgresql_port: '5432',
         postgresql_database: '',
+        // If `undefined`, it's not included in the patch update request, and will then
+        // not be changed.
+        postgresql_password: this.update ? undefined : '',
         postgresql_schema: 'public',
         postgresql_table: '',
         postgresql_sslmode: 'prefer',
@@ -176,7 +172,7 @@ export default {
           required: helpers.withMessage(
             this.$t('error.requiredField'),
             requiredIf(() => {
-              return this.allowedValues.includes('postgresql_password')
+              return this.values.postgresql_password !== undefined
             })
           ),
         },