Troubleshooting
Login / setup
Section titled “Login / setup”Not logged in. Run pywa cloud login first. — every command except login needs a
stored token. Run pywa login.
Could not reach the control plane at <url> — the CLI couldn’t connect at all (wrong
--api-url, the control plane isn’t running, or a network/firewall issue) — distinct from an
authentication failure, which would connect fine and return a 401/403 instead.
Invalid email or password (signup/login) — exactly that; there’s no separate “account
doesn’t exist” vs. “wrong password” message, deliberately, so a failed login attempt can’t be used
to enumerate which emails have accounts.
Deploy failures
Section titled “Deploy failures”pywa deploy prints the full build log on failure — read it top to bottom, the actual error
is almost always in there, not just “build failed.” A few failure modes worth knowing about
specifically:
Python syntax check failed— every.pyfile in your project is checked before a Docker build even starts, so a syntax error fails fast with a clear file/line rather than a slower, vaguer Docker build failure. If you’re on macOS and see a syntax error in a file you don’t recognize (e.g.._main.py), that’s not your code — see below.- A file like
._main.pyshows up in the error — macOS’starcommand writes an invisible “AppleDouble” metadata file (._<name>) alongside any file with extended attributes when you archive a project by hand. These are automatically ignored during the syntax check, so this shouldn’t happen from a current CLI/dashboard version — if you see it, you’re likely using an old version or building the archive with a different tool; update and retry. Project must include one dependency file: uv.lock, pylock.toml, pyproject.toml, or requirements.txt— exactly that; add one of these declaringpywa[server](not justpywa— the[server]extra is what pulls in the ASGI server Pywa Cloud’s runtime actually runs). If the file is present but doesn’t declare the right extra, the build itself will still succeed, but the container will fail at startup instead (see “keeps restarting” below) - this check only catches the file being missing entirely.- Archive too large — the current limit is 50MB. Make sure
.venv/__pycache__/.gitaren’t being included (they’re excluded automatically by the CLI’s own archive builder, but a hand-built archive via the dashboard’s file-upload flow won’t get that for free). - Build timed out — the default build timeout is 10 minutes. A build that legitimately needs longer than that (a very large dependency set) is unusual - check whether a dependency is hanging on a slow/unreachable index first.
After a successful deploy, the bot keeps restarting
Section titled “After a successful deploy, the bot keeps restarting”Check pywa cloud status for restart_count and whether it’s flagged as a likely restart loop,
then pywa cloud logs for what’s actually crashing. The most common first-deploy cause: pywa’s
own server refuses to start without a verify_token -
Error: When listening for incoming updates, a `verify_token` must be provided.— meaning PYWA_VERIFY_TOKEN (and usually PYWA_TOKEN/PYWA_PHONE_ID) aren’t set yet. Either set
them by hand (pywa cloud env set PYWA_VERIFY_TOKEN ...) or, more commonly, connect a real
WhatsApp number first (pywa cloud connect) — completing that flow sets all of these
automatically. A crash-looping bot with no WhatsApp number connected yet is expected, not broken.
Health check says “unhealthy” — what do the reasons mean?
Section titled “Health check says “unhealthy” — what do the reasons mean?”pywa cloud health reports one of:
webhook_challenge_rejected— this one means healthy. pywa’s webhook handler correctly rejecting an unauthenticated challenge request (HTTP 403) is exactly what a real, running pywa server does — the naming is about what the check itself did, not the outcome. This is also whypywa cloud logsperiodically shows aWARNING pywa.server: Failed verification challenge: invalid verify tokenline even on a perfectly healthy bot — that’s this same health check hitting your bot, not a real failed request from Meta or a customer.not_running— the container isn’t running at all; checkstatusfirst.no_port_mapping— the container is running but has no recorded port to check yet (typically right after a deploy) — retry in a few seconds.unreachable— the container is running but didn’t respond to the health check at all (still starting up, or genuinely stuck) — checklogs.unexpected_response— the container responded, but not with the specific 403 a real pywa webhook handler gives — worth checkinglogsfor what’s actually being served.
Still stuck?
Section titled “Still stuck?”Include the full output of pywa cloud status, pywa cloud health, and the last 50-100 lines of
pywa cloud logs when asking for help — most of what’s needed to diagnose a stuck deploy is in
those three, not in describing the symptom alone.