Oh yeah we've had those as well. I kinda feel two things about these at the same time.
At a practical level, these situations sucked. Someone had to search for the common expression, look at each instance, decide to change it to the central place or not. They spent 2-3 days on that. And then you realize that some people were smart and employed DRY - if they needed that one expression 2-3 times, they'd extracted one sub-expression into a variable and suddenly there was no pattern to find those anymore. Those were 2-4 fun weeks for the whole team.
But at the same time, I think people learned an important concept there: To see if you are writing the same code, or if you're referring to the same concept and need the same source of truth, like the GP comment says. I'm pretty happy with that development. Which is also why my described way is just one tool in the toolbox.
Like, one of our code bases is an orchestration system and it defines the name of oidc-clients used in the infrastructure. These need to be the same across the endpoints for the authentication provider, as well as the endpoints consumed by the clients of the oidc provider - the oauth flows won't work otherwise.
And suddenly it clicked for a bunch of the dudes on the team why we should put the pedestrian act of jamming some strings together to get that client-id into some function. That way, we can refer to the concept or naming pattern and ensure the client will be identical across all necessary endpoints, over hoping that a million different string joins all over the place result in the same string.
In such a case, early or eager DRY is the correct choice, because this needs to be defined once and exactly once.