--- title: "1.21.1 — Working job requeue, honest SMS failures, test messaging isolation" description: "django-mojo 1.21.1 repairs the operator recovery for stranded background jobs — it previously published where no worker looks and reported success — makes phone-verification send failures honest (retryable when the provider is unavailable, explicit when the number cannot receive texts, no more raw s…" date: "2026-08-28" tags: ["release"] canonical: "https://django-mojo.sitesmojo.com/changelog/1-21-1/" --- django-mojo 1.21.1 repairs the operator recovery for stranded background jobs — it previously published where no worker looks and reported success — makes phone-verification send failures honest (retryable when the provider is unavailable, explicit when the number cannot receive texts, no more raw server errors on a half-configured provider), rate-limits the public account-deactivation confirmation endpoint with token-free throttle diagnostics, and adds an opt-in test-only Pub/Sub prefix so test checkouts sharing one Redis server stop receiving each other's messages and job-control broadcasts. Patch release; no consumer action required — production channel names and all success behavior are unchanged. ### Added - Opt-in test messaging isolation: a new file-static `REDIS_PUBSUB_PREFIX` setting (default empty) namespaces every framework Pub/Sub channel — job runner control, broadcasts, replies and pings, and realtime broadcast/topic/direct messages — so test checkouts sharing one Redis server no longer receive each other's messages or job-control commands. With the default empty prefix, production and development channel names are byte-identical to before. - Framework test checkouts derive their prefix automatically, and an explicitly isolated test run whose prefix is missing or mismatched now fails visibly instead of silently talking on shared channels. ### Changed - Phone verification send now answers provider and transport failures with a retryable 503 carrying a fixed safe message, and provider rejections of the number itself with a fixed 400 saying the number cannot receive texts — replacing the blanket 400 that blamed the phone number for every failure. Success responses, verification codes and rate limits are unchanged. - An operator requeue of a job channel now sweeps the channel's entire pending backlog instead of silently capping at the reset count; the sweep is bounded per request (configurable, default 5000) and reports when it truncated so it can be run again. ### Fixed - Requeued database-pending jobs now land on the queues workers actually consume. The recovery previously published to a legacy location nothing reads — it converged successfully, reported jobs requeued, and recovered nothing. - A phone-verification sender number configured without provider credentials no longer fails the request with a raw server error; it reports the same retryable failure as any other transport problem. - The "verification code sent" account-security event no longer fires when no provider accepted the message. ### Security - The public account-deactivation confirmation endpoint now carries its own rate limit (10 requests per IP per hour, with Retry-After). Its throttle events record only the source IP — the emailed token is never persisted, even when a caller sends it in the query string. - Malformed job channel names are rejected before an operator requeue can write them into queue keys, metric names or incident titles. ### Upgrade notes - Clients that matched the old phone-verification failure message ("check your phone number") should key on the response body's code instead: 503 means try again shortly, 400 means the number cannot receive text messages. Deployments running the legacy 200-on-error shim receive both bodies over HTTP 200 as before. - Framework test checkouts must regenerate their testproject after upgrading (`bin/create_testproject`) — the test runner now refuses to run with a missing or mismatched messaging-isolation prefix.