Reasonable clarification. My response to your original "never do this" is a is a bit more specific then. There are two broad userspace concurrency models: cooperative and preemptive. Cooperative is a "sometimes the right call, sometimes more trouble than it's worth" situation; I can see what you're getting at there. But you're flat wrong about preemptive.
Cooperative concurrency: it depends. It's sometimes the right move, but has drawbacks. It's usually implemented to enable efficiency or partial parallelism of kernel-space code (IO). There are plenty of platforms that absolutely need it for that purpose: c10k, nodejs's rise to fame, all that. It behaves poorly when mixed with non-cooperative (blocking) code, and is poorly understood by many folks who expect userspace code to be parallelized as well. A common claim is that cooperative concurrency is harder to use than pre-emptive, but that's not true: some common things are harder, but some less common, but more dangerous things like race conditions tend to be much easier. Tokio and other cooperative systems that schedule onto fixed kernel threads can help with the hard parts a bit, but it's a partial mitigation at best.
Preemptive userspace concurrency: firmly disagree with your original point. Green threads are usually combined with userspace-code parallelism (e.g. goroutines scheduled onto multiple threads) and efficient kernelspace interactions (IO multiplexing). In the popular implementations of green threads I know well (Erlang and Go), this is an unalloyed blessing, in that it both removes many of the dangerous edges of threaded programming, facilitates increased efficiency, and lets users semantically model concurrency/parallelism with much less fear of e.g. creating too many threads, torn reads, etc. That's a big benefit: now we can model things like actors or CSP as subprograms written in procedural, synchronous, ordinary-looking code without getting Ph.Ds in operating system internals or having to carefully reason about complex interlocking layers of callbacks and futures to minimize risk of blocking or deadlock. In many ways, this brings the good parts of single-responsibility/what folks call "the UNIX philosophy" into a single process with minimal pain.
Rare cases where the userspace-concurrent runtime fights with your ability to interact directly with the OS, as with Docker's fork/thread/process-global-state challenges, do emerge. But I don't think those are primarily because of userspace concurrency; rather, they're because it's hard to do low-level things in a high-level, managed runtime. You can fork in the JVM, too, and you'll have problems. Different ones, because the runtime's different (e.g. endless RSS burn at idle due to the child GC moving parent objects), but problems all the same. Same for Python: forking in the presence of regular OS threads and/or a running event loop is equivalent to arming a minefield; doable but troublesome, just like it was for the Docker folks with Go.
To be fair, some of the same pains as the cooperative model appear with pre-emptive, too, when userspace concurrency systems are retrofitted onto runtimes that do a lot of other kinds of concurrency as well--but that's because of the hybrid/retrofit nature of the product, and not because of green threading as a concept. Java's rocky adoption of virtual threads is an example of that.