When you call run, you have to pick a value for 'i. You must pick a lifetime that is short enough to satisfy the requirement that E has no references shorter than 'i.
It's not really that E is referencing 'i or that 'i is referencing E here. It's just a constraint that something must be true, and it doesn't have a "direction".
Ideally parse and run functions would be able to return errors like CommandError<'i> which is an error that refers to an input: &'i str, but we don't want the parser to be tied to a specific input: &'i str, only the parse results, and the error type needs to be known so that a command can specify requirements on it like so:
impl<E: CommandError> Command<(), (), E> for MyCommand {
...
}
(because there's no way to restrict what an fn accepts except by shoving it in the impl/trait)
If you try to actually implement what you described in words, you'll run into problems. In this implementation, we're implementing for any possible lifetime 'err. And we've bound the method to cases where E: 'r. Now, consider the case of 'err = 'static. The bound E = SpanErr<'static>: 'r holds for any possible 'r, so we have to implement the method... for any possible 'r. When 'r is strictly less than 'static, the body of the implementation tries to turn a &'r str into a &'static str by extending lifetime 'r. Hence, the error.
From a practical standpoint, without changing the trait as written, you can only return non-reference carrying errors.
The problem is that you don't really wantE: 'r. You really want something like 'r: E. Unfortunately, this is not an accepted syntax.
You can use a GAT on nightly. One downside here is that your implementation for SpanErr<'static> will still return a SpanErr<'r>, which might be confusing elsewhere. Or more generally speaking, your implementation ignores the lifetime of E and you always get back a lifetime of 'r. You might not notice if your lifetime-bound Es always match the input of CommandContext. On the upside, the signature of your trait is unchanged.