The refactoring tool Drupal never gave me: merging fields in Craft (and the bug that skipped my conditions)
Every long-lived content model grows duplicates. You add ctaDonate for one section, ctaAbout for another, and two years later you've got six near-identical fields that should be one. In Drupal, consolidating those usually means a custom migration or an update hook and a careful afternoon. Craft has a CLI command that does it for you — and I was genuinely impressed, right up until I found the bug that quietly skipped my conditional fields.
The tool Drupal never gave me
Since Craft 5.3 (Aug 2024) there are three commands: fields/auto-merge ("Finds fields with identical settings and merges them together"), fields/merge (you name the handles to combine), and entry-types/merge (merge two entry types). They don't just repoint references — they rewrite field layouts, update project config, combine search keywords, and generate the content migration to move data. The upgrade guide's "Field and Entry Type Consolidation" section lays out the workflow: do it only "after getting your project fully upgraded and deployed," run them in order (auto-merge, then merge, then entry-types/merge), and — the line that matters for a team — "You must commit these files to version control and run craft up in all other environments." A merge isn't a database action you repeat per environment; it's a project-config change you commit once and replay everywhere with craft up.
Coming from Drupal, that's the part that made me sit up. There's no core equivalent I know of — field-storage consolidation across bundles is hand-rolled work. (I'm hedging that against my own memory; I didn't go survey every contrib "field tools" module before saying it.) Craft treats "clean up the sprawl" as a first-class, version-controlled operation. That's a genuinely nice idea.
The catch
On 8 Oct someone filed issue #19901: the merge commands were skipping changes. Specifically, a merge did not update field conditionRules that referenced the merged fields, and did not update fields inside Content Blocks. So if you had a conditional field — "show this only when that other field is X" — pointing at a field you just merged away, the condition silently kept referencing the old field. No error. The reporter guessed the conditions store IDs rather than UIDs; Brandon Kelly closed it the next day with "Fixed for the next release," and the 5.x "Unreleased" changelog now admits the commands "weren't updating field condition rules that referenced the merged fields" and "weren't updating Content Block fields' layouts."
The irony is that auto-merge — the one sold as the safe, automatic path — is exactly the one that missed the conditions. "Automatic" and "trust it blindly" aren't the same word.
There's history here, too: entry-type merges have a trail of bugs with Single sections — content lost or entries duplicated (#16087, #16102, #16394, #16628). None of that means don't use these commands. It means use them the way you'd use any tool that rewrites your whole content model at once: deliberately.
How I'd run it
- Merge on a fully upgraded, deployed project, never mid-migration — the docs are explicit, and the Single-section history is why.
- Diff
config/project/after every single merge. This is the whole safety net. A merge touches fields everywhere; the diff is where you catch a condition rule that didn't come along. - Hand-check your conditional fields and Content Block layouts until you're on the release that fixes #19901. As of 20 Oct the latest stable is still 5.11.5.1 and the fix sits unreleased — so if you're reading this later, re-check Packagist, because a 5.11.6 may have shipped.
- Commit, then
craft upeverywhere. Don't re-run the merge per environment; replay the committed config.
One honest limit: the docs never actually define how auto-merge decides two fields are "functionally identical" — it audits and lets you accept or skip batches, but I can't tell you the exact criteria, so I wouldn't let it run unattended on a big model. And I haven't run this on production data myself; this is me reading the docs and the bug, not reporting a scar.
The takeaway
This is one of those Craft tools that makes a Drupal developer a little envious — a real, version-controlled "consolidate the mess" command. Just remember it rewrites everything at once, and until the current fix ships it can leave your conditional logic pointing at a field that no longer exists. Merge, diff the project config, check your conditions, deploy. The tool does the heavy lifting; you still own the review.