The timing of relevant parts of the process is following:
- Query executes and fetches posts (or in this case no posts)
template_redirect
fires- Template file is determined from query variables and loaded
When you change query variables in template_redirect
you change template choice (which you observe), but you still have no posts in query.
The functions still work, they just don’t have a post to work on.
It’s quite a peculiar case, because which posts would you expect in an archive that is 404 and has no posts?
I am not sure without playing with such a setup but I would probably try to redirect “ahead” rather than “fake” valid page out of 404.