If a command accepts a write concern, it will always call waitForWriteConcern, no matter if and how it fails. The only question is what OpTime it waits for. If no write was attempted (and consequently the GlobalLockAcquisitionTracker did not move forward the client opTime), we will simply wait for write concern on the client opTime from before the command began. The client opTime may be null, in which case we don't do any waiting, or may already be committed in which we also do no waiting: https://github.com/mongodb/mongo/blob/0bc90017e2563ed7432d56051483763c91d28025/src/mongo/db/service_entry_point_mongod.cpp#L77-L88
If there was a previous uncommitted write on the client, however, we end up waiting for write concern on the previous write, even if the current command received a parse error and should do no waiting. Alternatively, if that previous write was in a previous term, waitForWriteConcern will fail here instead of waiting on it or skipping waiting entirely: https://github.com/mongodb/mongo/blob/0bc90017e2563ed7432d56051483763c91d28025/src/mongo/db/repl/replication_coordinator_impl.cpp#L1489-L1496. In the case where no write was even attempted, rather than wait on the previous write, we should not call waitForWriteConcern at all and just return early. This will prevent waiting on previous writes when unnecessary and failing commands unnecessarily when they shouldn't need to wait for write concern at all.
There is an assumption here that if we do not attempt to take the GlobalLock at any point then we should not wait for write concern at all. This is not always true, such as with retryable writes retrying successful operations(
SERVER-33475), in which case those commands should push the client OpTime forwards themselves to ensure we wait on the proper opTime.