I'm baffled by this and hoping someone can explain this behavior to me.
I have a sample apex app here https://apex.oracle.com/pls/apex/f?p=126734:2 (admin credentials: username: guest pw: cubsarechamps).
I just want to enter a value on page 2 in text field P2_SOURCE and then click the button and be redirected to page 3 and have the value from P2_SOURCE populate P3_TARGET. I know that I need to set the value of P2_SOURCE in session and so I created a 'lose focus' dynamic action with a plsql process of null that also submits P2_SOURCE.
After I enter '123' in P2_SOURCE I tab out of the field to trigger the DA, and then I click session in my developer toolbar and I can see that the value of P2_SOURCE is indeed '123'. Then I click my button to go to page 3 but nothing is passed to P3_TARGET (unless I actually submit my page first, which I shouldn't have to do, right?).
So my question is why P2_SOURCE isn't being passed to P3_TARGET. The item is set in session state so why is &P2_SOURCE. passing a null value when there is a value set in session? Can I not use page item substitutions unless I actually submit my page? The documentation seems to indicate this is supported functionality.
Substitution Strings are evaluated when the page is loaded and so, it is NULL in your case as the page item contains no value in the beginning. I would either use Dynamic Action with JavaScript Expression or Branch Process.