For the built-in formatting there is no other option. It really must be a literal.
You will have to find another solution, e.g. use .replace to perform your own substitution, and/or call .to_string() on values yourself, or combine multiple smaller format! or format_args! together.
The compiler needs to know the format argument at compile time to be able to parse it and generate code which does the formatting for that specific format argument. You could use something like the runtime-format crate though.
@bjorn3 Thanks for clarification that for format!, the "compiler needs to know the argument at compile time". I thought if the arguments were compile time strings or even static strings the issue would be resolved, but it looks like the format! format string can only be a 'literal' in this case.
Also thanks for the reference to the runtime-format crate. This is precisely what I was looking for (since I actually do have runtime arguments), but I just ended up using String.replace as per an earlier suggestion in order not to add another crate dependency.