Mutation isn't bad. Shared mutation is bad. The bug arrives when one piece of code grabs a reference to an object, holds onto it, and another piece of code mutates the original. React's component-state model exists almost entirely to prevent this: returning a *new* state object, not mutating the existing one, lets every consumer rely on prev !== next to detect change.
The classic non-React shapes: a function that takes a list and .sort()s it in place (mutating the caller's list), a constants module that ships an exported array which a consumer pushes to, a config object whose middleware modifies on its way through.
The defense is a design pattern: prefer immutable data structures at API boundaries, prefer returning new values over mutating in place, and use language-level enforcement when available (readonly in TypeScript, Object.freeze, Rust's borrow checker, Clojure-style persistent collections).
Review heuristic
Library functions that take an object and mutate it should be loud about it (named sortInPlace, not sort). Sites that pass a config object through a chain of middleware should not allow any link in the chain to mutate it.