microsoft / microsoft/vscode

Settings Sync: conflict actions use two contradictory naming schemes, causing accidental data loss

Open
#331,037 0 comments 0 reactions 1 assignee Claimed by @sandy081 View on GitHub
settings-sync
Dominant language
TypeScript
Stars
193k
Forks
42.4k
PR merge metrics
PR metrics pending

Description

## Type

Bug / UX

## Version

- VS Code: 1.130.0 (commit `1b6a188127eeaf9194f945eb6eb89a657e93c54c`, x64)
- OS: Linux 6.1.0-51-amd64 (Debian)
- Display language: German (`ms-ceintl.vscode-language-pack-de`), but the
problem exists in the English strings as well.

## What happened

Settings Sync reported a conflict for `settings.json`. I picked the action
labelled **"Replace Local"**, expecting it to mean *"the local side is the one
to keep"* — the label leads with "Local", and the neighbouring dialog in the
same feature uses "Accept Local" to mean exactly that.

It meant the opposite. Four local settings keys were deleted and one value was
reverted to the remote state:

- `yaml.disableSchemaDetection` (6 globs) — deleted
- `git.autoRepositoryDetection` — deleted
- `githubPullRequests.experimental.chat` — deleted
- `githubPullRequests.experimental.useQuickChat` — deleted
- `git.openRepositoryInParentFolders` — reverted from `prompt` to `always`

There is no undo for this and no in-product warning that a destructive
overwrite is about to happen.

## Root cause: the same decision has two opposite naming schemes

Settings Sync labels one and the same choice in two mutually inverted ways,
depending on which surface the user happens to be on:

| Source | Key | English string |
|---|---|---|
| `src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts` | `replace local` | `Replace Local` |
| `src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts` | `replace remote` | `Replace Remote` |
| `src/vs/workbench/contrib/userDataSync/browser/userDataSyncConflictsView.ts` | `acceptLocal` | `Accept Local` |
| `src/vs/workbench/contrib/userDataSync/browser/userDataSyncConflictsView.ts` | `acceptRemote` | `Accept Remote` |
| `src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts` | `replace local` | `Accept &&Remote` |
| `src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts` | `replace remote` | `Accept &&Local` |

Note the last two rows: the internal key `replace local` renders as
**"Accept Remote"** in one place and as **"Replace Local"** in another. Both
are technically correct — replacing local *is* accepting remote — but the
user-visible words are inverted between two surfaces of the same feature.

"Replace X" names the **victim** of the operation. "Accept X" names the
**winner**. A user who has seen one scheme will systematically misread the
other, and the failure mode is silent, irreversible data loss.

## Proposal

Use one scheme everywhere, and prefer the one that names the outcome rather
than the casualty:

- **Keep Local** (local wins, remote is overwritten)
- **Keep Remote** (remote wins, local is overwritten)

"Keep X" cannot be misread the way "Replace X" can: it states what survives.
"Accept X" is an acceptable second choice — it also names the winner — but
then `Replace Local` / `Replace Remote` should be retired rather than kept
alongside it.

Optionally, add the consequence as secondary text on the destructive action,
e.g. *"Keep Remote — your local settings.json will be overwritten"*.

## Related (all closed, none covering the inconsistency itself)

- #90923 — "Replace (Overwrite Local)" button wording
- #133262 — Unclear copy for what sync settings will be replaced
- #108014 — Add "Replace Remote" to Settings Sync Turn On options
- #162884 — Settings Sync conflicts merge editor uses primary buttons

## Separate follow-up

The German localization drops the direction entirely on one of these buttons.
Filed separately as microsoft/vscode-loc#2380.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.