Mass replacement is an old dream: change one pattern into another across all the code in a single move. Ordinary find and replace does this literally but stumbles where each place needs a slightly different decision. Vibe and Replace is an evolution of the same idea: it finds exact text matches and applies an AI instruction to each, that is, it changes not by a template but by the meaning of the place.
The naive move is to set an instruction, throw the scope open to the whole repository and trust the model: it is smart, it will figure out each case. The temptation is strong because it promises to close a boring mechanical task in one pass. And often the first few replacements do look correct, which strengthens trust exactly before it fails.
It breaks on scale and on the nature of the tool. The model applies the instruction to each match independently and plausibly, but not with a guarantee; over a hundred places a few will almost certainly turn out unlike the rest. If the scope is wide from the start, those few drown in a general diff that is already impossible to review by eye meaningfully. The tool's power here turns against verifiability.
The professional technique is to move from narrow to wide and keep the replacement verifiable at each step. First limit the directory and the pattern, look at how many matches it gives, apply the instruction to a small set and make sure the result is exactly right. Only after that widen the scope. This is not a documented button but engineering discipline: the product provides a replacement by meaning, while responsibility for the size of the step stays with you. A small set here is not over-caution but a way to see the worst case before the best: if the instruction errs somewhere, it is cheaper to meet that error on five places than on five hundred.
The choice of mode is part of this discipline. Fast uses a faster model and applies changes quickly; Smart uses a slower and more careful one. You switch between them with the button next to the instruction field. Fast fits where the edit is homogeneous and mechanical and each place is like its neighbor. Smart fits where each match requires understanding the context and the cost of a wrong edit is higher than the gain in speed.
Why the tool deliberately keeps judgment local rather than taking on the whole migration. It is strong at exactly one thing: applying a clear instruction to many similar places. It knows nothing of what is outside the text - schema compatibility, public API contracts, callers in other repositories. Reducing a whole migration to it would mean entrusting a text replacement with a decision that requires a plan, not a rewriting of lines.
Hence a firm boundary: Vibe and Replace is not a migration engine. Changing the data schema, the public API or the semantics of behavior requires a separate backward-compatibility plan, not just a replacement across all files. A mass text edit changes how the code looks but does not by itself prove that the migration is correct and broke nothing beyond the changed lines.
The cost of inattention grows linearly with the scope. One wrong instruction applied to five places is a minute of manual fixing. The same instruction over five hundred places is a diff no one will read in full, with a handful of quiet errors inside, discovered later one by one. The wider the first pass, the more expensive it is to sort out the consequences.
The tool is justified where the task is honestly mass and homogeneous: rename a concept, fix a single stylistic pattern, bring calls to a new signature where the differences between places are small. The more each place differs from the others, the less this is work for a single pass and the more it calls for either Smart with a narrow scope or a regular agentic loop with a plan. A useful sign of the boundary is simple: if, to replace correctly, the model needs to know more about each place than is visible in the match text itself, this is no longer a mass-replacement task.
The result must be checked by a different means than it was made. The replacement went by text - check it not by text but by behavior: search for the old pattern again (ideally zero matches where you expected a replacement), run typecheck and the tests, review the diff along the scope's boundaries. If the old pattern still appears or the tests went red, the replacement is not finished, however convincing the individual edits look.
The typical failure is taking the size of the diff for a measure of work rather than of risk: being glad that "it replaced everywhere" and closing the task without narrowing the first pass or checking behavior. The sign is simple: an edit is handed over by the number of changed places rather than by a green run and an empty re-search. Start with a small set and check by behavior - then mass scale becomes the tool's strength rather than a source of mass errors.