Is it possible to have multiple concurrent coprocesses?

From the "BUGS" section at the very end of the bash manual:

There may be only one active coprocess at a time.


Q1: Is it possible to have multiple coprocesses running at the same time?

On Bash v4 and above (including current v5), officially no, as noted by @Kusalananda.

However, I can tell you that it might work despite the warning, but of course no guarantee and YMMV. See here for a bit more insight.

Q2: If so, how should the script above be modified to achieve the desired output?

It might (as per above) work just fine once you fix the:

exec {INNER_READER}<&"{INNER[0]}"  # <-- lacks the '$' sign for the 'INNER[0]' variable

which causes the:

./coproctest.sh: line 19: INNER_READER: ambiguous redirect

message, and consequently also the:

./coproctest.sh: line 21: read: : invalid file descriptor specification

message.

It works for me, once fixed that and warning aside.

As for other notes:

  • There's no need to duplicate a coproc's file-descriptors, unless you want to pass them to a child process (a sub-shell or a command or script)
  • You probably did so because the seq command naturally finished quickly, and thus the automatic variables disappeared before you could use them. By doing the way you did, those duplicate file-descriptors will be inherited by all subsequent commands and background processes, which might be undesirable if your co-process actually uses its input pipe and waits for it to be closed in order to exit. So another approach to address that is by a synchronization mechanism, like for instance make your OUTER co-process be { seq 3; exec >&-; read; }, and then when you've consumed its input from the main script do e.g. echo >&${OUTER[1]}; wait "${OUTER_PID}" to let the co-process's read proceed then wait for it. Note that it is not guaranteed that the wait will execute before the $OUTER_PID variable disappears: in such case you can just mute the warning message (or ignore it altogether) and perhaps force a success status with an || true
  • As a personal side-note I can tell you that, if you are really determined in having multiple co-processes simultaneously, you might re-implement a rough equivalent of coproc using Bash v3 syntax over background processes plus mkfifo named-FIFOs, and on Linux also with a trick with Process Substitutions instead of mkfifos. With Bash v4 syntax it can be less complicated, but still a challenging exercise.