It doesn't work because the toUpperCase() is applied at the string "$1" and then the result of that operation i passed as second argument of the replace method; you instead expect that toUpperCase is called with the value found. To do so, you need to pass a function as second argument of replace:
"\u001b[31merror\u001b[39m".replace(/(error)/, $1 => $1.toUpperCase())
That would work (notice, $1 here is just an arbitrary variable name, you can call it as you want).
However, since you said that error is just an example, you could either list all the possible values:
mystring.replace(/(error|info|warning)/, $1 => $1.toUpperCase())
Or just replace everything is between \u001b[31m and \u001b[39m (assuming they don't change):
const mystring = `\u001b[31merror\u001b[39m`;
console.log(
mystring.replace(/\u001b\[31m(.*)\u001b\[39m/, $1 => $1.toUpperCase())
);
Hope it helps.