Two encodings that look identical until they are not
Encoding a URI leaves the characters that give a URL its structure alone: the colon after the scheme, the slashes between path segments, the question mark that starts the query, the ampersands between parameters. That is right when you are cleaning up a whole address that happens to contain a space or an accented character.
Encoding a URI component escapes those same characters, because in that context they are not structure - they are data that must survive being embedded inside somebody else structure. Get this backwards and the symptom is specific and maddening: everything works until a value contains an ampersand, at which point the receiving end reads one parameter as two and the second half of your value vanishes.
The redirect parameter is where this always bites
A login page that takes ?next=/dashboard is fine until the destination has a query string of its own. Now you are putting a URL inside a URL, and the inner one has to be component-encoded or its question mark terminates the outer query and its ampersands split it. Half the open-redirect bugs and most of the lost-return-path bugs in the world start here.
The same applies to anything carrying a URL as a value: OAuth redirect_uri, tracking links wrapping a destination, webhook callbacks, and the share links that social buttons build. If a URL is the value of a parameter, it is a component, and it needs the encoding that escapes structure rather than the one that protects it.
Why a space is sometimes a plus sign
Percent-encoding turns a space into %20. The plus sign comes from a different specification - the form encoding browsers use when submitting a query string - where a space is a plus and a literal plus must itself be escaped. Both are correct, in their own context, which is why they coexist and confuse everyone.
The practical rule: in a path, a space is always %20. In a query string, %20 is accepted everywhere and a plus is accepted by most things, so %20 is the safer choice when you are building the URL yourself. If you are decoding something that came from a form submission and pluses are appearing in your text, that is what happened.