You cannot directly use shell syntax constructs like { code; } or ; or & or | in arguments you pass to screen (or parallel, or xargs, or etc).  The shell will try to parse your command before running it, so anything which looks like
echo | moo |
will be parsed into a pipeline with the commands echo and moo and nothing (which is of course a syntax error).  If you want to echo a pair of literal pipe characters, you have to quote them:
echo '| moo |'
If you want the quoted stuff to be evaluated after the shell parses it, there are a couple of options.
- Encapsulate the command externally in a script, so that you can say screen myscriptand have the actually useful commands in the script filemyscript. (Some useful tools even allow you to use shell functions or even aliases here.)
- Pass the command sh -c 'morecommands'orbash -c 'morecommands'so that the commands are quoted but end up being executed anyway.  This is just another form of encapsulation really, but doesn't require a separate external definition like a script file or shell function.
So in your example, you could put your code in a script like ./metarunner and then just call screen ./metarunner; or quote the command line like
screen sh -c "parallel --colsep '\t' -j 100 -m sh $HOME/runner.sh {} <$HOME/input"
(I switched ~ to $HOME here so I could use sh instead of bash. If you need nontrivial Bash features or are too lazy to refactor your code into POSIX shell script, obviously use bash -c instead of sh -c.  See also Difference between sh and bash for what the differences are exactly.)
Tangentially, I also got rid of the useless use of cat.