Found during the V2 catch-up (#36), not fixed there.
apps/mobile/src/state/thread-outbox-model.ts (shouldRetryThreadOutboxDelivery, around lines 267-283 on sync/upstream-20261005) switches on the V1 tag OrchestrationDispatchCommandError, which V2 servers no longer throw. V2 failures (OrchestrationV2DispatchCommandError, OrchestrationV2ThreadLaunchError) fall through to message-text sniffing, so whether a server-decided refusal restores the draft or is retried as a transport failure depends on its wording (isTransportConnectionErrorMessage). The drain hold was ported to match both V2 tags with reason: "server-draining" (4dd0f74); every other V2 refusal is still unmatched. Upstream has the same code.
Found during the V2 catch-up (#36), not fixed there.
apps/mobile/src/state/thread-outbox-model.ts(shouldRetryThreadOutboxDelivery, around lines 267-283 onsync/upstream-20261005) switches on the V1 tagOrchestrationDispatchCommandError, which V2 servers no longer throw. V2 failures (OrchestrationV2DispatchCommandError,OrchestrationV2ThreadLaunchError) fall through to message-text sniffing, so whether a server-decided refusal restores the draft or is retried as a transport failure depends on its wording (isTransportConnectionErrorMessage). The drain hold was ported to match both V2 tags withreason: "server-draining"(4dd0f74); every other V2 refusal is still unmatched. Upstream has the same code.