Gateway Troubleshooting
Common gateway issues and step-by-step solutions
Common issues with the PraisonAI Gateway daemon and server, with step-by-step troubleshooting guides.
from praisonaiagents import Agent
agent = Agent(
name="Gateway Helper",
instructions="Diagnose PraisonAI Gateway connectivity issues.",
)
agent.start("Gateway health check: is the daemon reachable?")The user checks gateway status, reads logs, and restarts the daemon until channels respond again.
Common Issues
Is this the core or a plugin/hook?
Symptom: The gateway misbehaves and you can’t tell whether the fault is in the gateway core or in an external plugin / inbound hook.
Boot core-only in one restart with Gateway Safe Mode:
praisonai gateway start --config gateway.yaml --safe-mode
# → logs: SAFE MODE: N inbound hook(s) disabled; external plugins skipped (PRAISONAI_NO_PLUGINS)If the fault disappears, it is a plugin or inbound hook; if it persists, it is the gateway core. Aliases --pure / --no-plugins are equivalent, and PRAISONAI_NO_PLUGINS=1 works for crash loops. Safe mode is replayed by restart — exit with a fresh gateway start without the flag.
Port Already In Use / Two Gateways Running
Symptom: Gateway fails to start with a clear error message about port conflicts.
Error: Gateway port 8765 is already in use.
Another gateway may be running (PID 8864).
Stop it: praisonai gateway stop
Only ONE gateway process may poll each bot token. To run a second,
isolated gateway give it its own state, bot tokens and port:
HOME=/srv/gateway-b GATEWAY_PORT=8766 praisonai gateway startA second gateway on another port that shares ~/.praisonai is refused by the state lock instead:
Error: another gateway already owns the state at /home/user/.praisonai (PID 12345 on 127.0.0.1:8765).
Two gateways sharing state poll the same bot tokens and write the same
queues, causing 409 Conflict errors and duplicate delivery.
Stop it: praisonai gateway stop
Or run an isolated gateway with its own state and bot tokens:
HOME=/srv/gateway-b praisonai gateway start- Check PID lock and port status
bash praisonai gateway statusLook for lines like:
Gateway PID lock: Process 12345 running (127.0.0.1:8765)Port 127.0.0.1:8765: In use
- Stop the existing gateway gracefully
bash praisonai gateway stopThis sends SIGTERM and waits for graceful shutdown. The gateway drains active sessions for up to 10 seconds — in-flight turns and queued inbox messages are persisted before exit. Sessions that exceed the timeout are force-persisted with a
SESSION_ENDevent (had_pending_work,was_executing). Use--forceto skip the drain. See Gateway Session Continuity. - If gateway is stuck, force stop
bash praisonai gateway stop --forceThis sends SIGKILL directly (SIGTERM on Windows) for immediate termination.
- If port is used by non-gateway process
bash # Find what's using the port lsof -i :8765 # Linux alternative: netstat -ano | findstr :8765 # Either kill that process or use a different port GATEWAY_PORT=8766 praisonai gateway start # Or: praisonai gateway start --port 8766 - Clean up stale lock file (if needed)
bash # Check the PID lock file cat ~/.praisonai/gateway-127_0_0_1-8765.pid # Check the state lock file cat ~/.praisonai/gateway.state.pid # Remove stale locks manually (auto-cleaned on next start) rm ~/.praisonai/gateway-127_0_0_1-8765.pid rm ~/.praisonai/gateway.state.pid ~/.praisonai/gateway.state.pid.guardOnly remove lock files when no gateway is running.
Stale locks are automatically detected and removed, but you can clean them manually if needed.
SSL Certificate Verify Failed on Start (Corporate Proxy / MITM)
Symptom: praisonai gateway start --config gateway.yaml fails with an SSLCertVerificationError in gateway doctor, but the same channel token works fine with --no-preflight.
Cause: Your network intercepts TLS with a corporate CA the probe’s HTTP client does not trust yet. The runtime bot adapter is often more permissive, so the token itself is usually fine.
Fix (pick one):
- Point PraisonAI at your corporate CA (preferred)
bash export PRAISONAI_SSL_CA_BUNDLE=/path/to/corp-ca.pem praisonai gateway start --config gateway.yamlPRAISONAI_SSL_CA_BUNDLEoverrides any pre-existingSSL_CERT_FILEandREQUESTS_CA_BUNDLEfor the probe. - Use the standard SSL env vars
bash export SSL_CERT_FILE=/path/to/corp-ca.pem # or REQUESTS_CA_BUNDLE praisonai gateway start --config gateway.yaml - Skip the preflight check
bash praisonai gateway start --config gateway.yaml --no-preflightSkips channel-credential validation on start. Use only when you know the tokens are good.
Gateway start aborts with ‘Turn pre-flight failed’
Symptom: praisonai gateway start exits with:
Turn pre-flight failed — the agent did not produce a reply: <detail>Cause: The channel credentials are valid, but the resolved agent’s model provider credential is missing / invalid / rate-limited / out of quota. The startup real-turn check (--verify-turn, on by default) sends one "ping" prompt to the agent and the model round-trip failed.
Fix (any of):
- Add the model/provider API key
bash # Add the key (e.g. OPENAI_API_KEY) to ~/.praisonai/.env, then: praisonai gateway start - Reproduce interactively
bash praisonai gateway test --turn ping - Temporarily skip the turn check
bash praisonai gateway start --no-verify-turnOr set
gateway.preflight.verify_turn: falseinbot.yaml. Use only when you know the model key is good (e.g. constrained/offline environments).
Telegram Bot Goes Silent After Restart
Symptom: Gateway /health endpoint returns healthy, but Telegram messages aren’t received after a restart or crash.
Cause: Two processes are polling the same Telegram bot token. Telegram delivers messages to only one poller, causing the bot to appear “silent” when the wrong process gets the messages.
- Stop all gateway instances
bash praisonai gateway stop --forceThis ensures all instances are terminated, even if PID files are corrupted.
- Verify no processes are running
bash praisonai gateway statusShould show:
Gateway PID lock: No lock file foundPort 127.0.0.1:8765: Available
- Start a single gateway instance
bash praisonai gateway startOnly start one instance to ensure exclusive bot token polling.
- Test bot responsiveness
Send a message to your Telegram bot. It should respond normally now that only one process is polling the token.
Daemon Running But Gateway Unreachable
Symptom: praisonai gateway status shows Daemon service: Running (launchd) but Gateway not reachable at http://127.0.0.1:8765/health.
- Verify daemon is actually running
bash praisonai gateway status --daemon-onlyLook for
Runningstatus and process ID. - Check daemon logs for errors
bash praisonai gateway logs # Or check raw log files: # macOS: tail ~/.praisonai/logs/bot-stderr.log # Linux: journalctl --user -u praisonai-botLook for Python tracebacks or port binding errors.
- Check port and PID lock status
bash praisonai gateway statusThis now reports both port usage and PID lock status directly. Look for:
Gateway PID lock: Process <pid> runningorNo lock file foundPort 127.0.0.1:8765: In useorAvailable
If another process is using the port, use
praisonai gateway stopto stop an existing gateway, or choose a different port. - Verify PraisonAI version
bash praisonai --versionUpgrade to ≥ v4.6.23 if you see older versions – earlier versions had IndentationError bugs fixed in PR #1484.
- Restart the daemon
bash # macOS launchctl kickstart -k gui/$(id -u)/ai.praison.bot # Linux systemctl --user restart praisonai-bot # Or reinstall completely praisonai onboard
Rapidly Growing Log Files
Symptom: ~/.praisonai/logs/bot-stderr.log grows to multiple MB per minute.
- Check log file size
bash ls -lh ~/.praisonai/logs/bot-stderr.logIf growing rapidly (>1MB/min), this indicates a crash loop.
- View recent errors
bash tail -50 ~/.praisonai/logs/bot-stderr.logLook for repeated Python tracebacks, especially IndentationError.
- Stop the daemon
bash # macOS launchctl unload ~/Library/LaunchAgents/ai.praison.bot.plist # Linux systemctl --user stop praisonai-bot - Clear logs and restart
bash # Clear the log file > ~/.praisonai/logs/bot-stderr.log # Upgrade PraisonAI pip install --upgrade praisonai # Restart daemon praisonai gateway install --start
Daemon Not Installed
Symptom: praisonai gateway status shows Daemon service: Not installed (systemd).
- Run the onboarding wizard
bash praisonai onboardThis installs the daemon service for your platform.
- Verify installation
bash praisonai gateway status --daemon-onlyShould show
Installed but not runningorRunning. - Start the service
bash # Manual start praisonai gateway install --start # Or check platform-specific commands praisonai gateway status
HTTP 500 on Health Endpoint
Symptom: curl http://127.0.0.1:8765/health returns 500 Internal Server Error.
- Check PraisonAI version
bash praisonai --versionVersions before v4.6.23 had AttributeError bugs in the health endpoint.
- Upgrade PraisonAI
bash pip install --upgrade praisonai - Restart the gateway
bash praisonai gateway install --start - Test health endpoint
bash curl http://127.0.0.1:8765/healthShould return JSON with status, uptime, agents, sessions, clients, and channels.
Windows: gateway status shows PID lock status: Unavailable
Symptom: praisonai gateway status prints an advisory PID-lock line, followed by a healthy gateway:
PID lock status: Unavailable (kill returned a result with an exception set)
Gateway Status: healthy
Uptime: ...On older versions (pre-v4.6.141) the same underlying cause produced a harder failure that hid the status entirely:
ERROR: Error checking gateway server status: returned a result with an exception setRoot cause: On Windows, os.kill(pid, 0) — used by GatewayPIDLock._is_process_running to poll whether a lock is stale — can raise SystemError (“returned a result with an exception set”) instead of OSError / ProcessLookupError. Before PraisonAI v4.6.141 that exception propagated through GatewayHandler.status and short-circuited the /health probe, so operators saw no gateway status at all.
What v4.6.141 changes:
_is_process_runningnow catchesSystemErrorandValueErrorand returnsFalse(process not running).GatewayHandler.statustreats PID-lock inspection as advisory only. Any unexpected exception printsPID lock status: Unavailable (<error>)and the command continues to the/healthprobe.
- Check your version
bash praisonai --versionUpgrade to ≥ v4.6.141 if you still see
ERROR: Error checking gateway server status: returned a result with an exception set. - Read the line as advisory
If
praisonai gateway statusnow printsPID lock status: Unavailable (<error>)followed byGateway Status: healthy, the gateway is running — the PID line is advisory only. - Confirm with the health endpoint
bash curl http://127.0.0.1:8765/healthA
200 healthyresponse confirms the gateway is up regardless of the PID-lock line. - Inspect the lock file if needed
powershell # PowerShell Get-Content $env:USERPROFILE\.praisonai\gateway-127_0_0_1-8765.pidThe lines are
pid,host,port,timestamp, and (since PR #4197) acreate_timestart-time fingerprint. The 5th line may be empty on older 4-line locks or when psutil is unavailable — the lock then degrades to the previous PID-only check. A stale PID is cleaned up automatically on the next start/stop/status call.
Windows: ‘charmap’ codec error from Telegram bot replies
Symptom: Telegram users receive Error: 'charmap' codec can't encode character '⚠' in position N: character maps to <undefined> instead of the real error message.
Root cause: Windows default console encoding is cp1252, not UTF-8. When agent exceptions contained warning symbols (⚠), emoji, or accented text, the error formatter crashed before the real error could be reported.
- Verify your version contains the fix
bash python -c "from praisonai.gateway.unicode_utils import safe_error_message; print('OK')"If this command runs without error, you have the fix from PR #1754.
- Upgrade to a fixed version
bash pip install --upgrade praisonaiUpgrade to PraisonAI version that contains PR #1754 — Gateway and Telegram bot error handlers now sanitize exception text to ASCII-safe form for transport, while preserving full Unicode in logs.
- Restart the gateway
bash praisonai gateway install --start - Test the fix
Users will now see clean error messages instead of charmap crashes:
Error: API quota exceeded. Check billing.(was: charmap crash hiding OpenAI 429)Error: Rate limit exceeded. Try again later.Error: Authentication failed. Check API key.Error: Request timeout. Try again.
Permission Denied Errors
Symptom: Daemon fails to start with permission errors in logs.
macOS
# Check LaunchAgent permissions
ls -la ~/Library/LaunchAgents/ai.praison.bot.plist
# Reload LaunchAgent
launchctl unload ~/Library/LaunchAgents/ai.praison.bot.plist
launchctl load ~/Library/LaunchAgents/ai.praison.bot.plistLinux
# Check systemd user service
systemctl --user status praisonai-bot
# Enable user lingering (allows services to run when not logged in)
sudo loginctl enable-linger $(whoami)
# Restart service
systemctl --user daemon-reload
systemctl --user restart praisonai-botWindows
# Run as administrator
# Check Task Scheduler for PraisonAI task
schtasks /Query /TN PraisonAIGateway
# Delete and recreate
praisonai gateway uninstall
praisonai gateway installClean Reinstall Process
When all else fails, perform a clean reinstall:
- Stop and uninstall
bash praisonai gateway uninstall - Clear configuration
bash # Backup first if needed rm -rf ~/.praisonai/logs rm -rf ~/.praisonai/config - Upgrade PraisonAI
bash pip install --upgrade praisonai - Run onboarding
bash praisonai onboardFollow the wizard to reinstall the daemon service.
- Verify installation
bash praisonai gateway statusShould show daemon running and gateway reachable.
Client stops reconnecting after agent_not_found
Symptom: GatewayClient logs Connection abandoned: agent_not_found (reconnect paused; not retrying) and stops attempting to connect, even though the gateway is healthy.
Cause: The agent_id supplied in the client’s hello frame is not registered on the gateway. The server emits agent_not_found with next_step: do_not_retry, and the client now correctly stops the reconnect loop instead of backing off forever.
- Check the agent_id you pass
python GatewayClient(url="ws://localhost:8765", agent_id="assistant") # ^^^^^^^^^ must exist on the server - List agents registered on the gateway
bash curl http://127.0.0.1:8765/health | jq '.agents'Compare against the id you’re passing.
- Fix the id or register the agent
Either update the client’s
agent_id, or add the agent to the gateway configuration and restart it. Then callclient.connect()again — the fresh call clears any stale backoff floor from the previous cycle. - Surface the failure without log scraping
Setting
client.on_reconnect_pausedbeforeconnect()gives you an immediate callback with(code, next_step)so the failure surfaces without waiting for a log scrape. See Gateway Client → Terminal vs Transient Connect Errors.
Cross-instance messages not being delivered / Redis pub/sub outage
Symptom: Subscribers on gateway B stop seeing messages that were published on gateway A. praisonai gateway status shows push.redis_degraded: true and a growing push.redis_dropped_writes; health()["degraded_owners"] lists route:redis-pubsub.
Cause: The Redis pub/sub connection that fans out channel messages across gateway instances dropped. Cross-instance delivery pauses until the adapter reconnects.
- Confirm the degraded owner and its retry_hint
bash curl http://127.0.0.1:8765/health | jq '.push, .degraded_owners'Look for
push.redis_degraded: trueand aroute:redis-pubsubentry whoseretry_hintpoints you atpraisonai gateway doctor. - Run gateway doctor
bash praisonai gateway doctorSurfaces the same record with the actionable hint.
- Verify Redis reachability from the gateway host
bash redis-cli -h <redis-host> pingA
PONGconfirms Redis is reachable; if it fails, fix the Redis connection or network path.
Recovery: No manual intervention on the gateway is needed. Once Redis is reachable again the adapter reconnects with bounded exponential backoff (1s → 30s cap), re-subscribes every channel, and clears route:redis-pubsub from degraded_owners. The log line to look for is Redis push adapter reconnected (server_id=<uuid>).
See Real-Time Push Notifications → HA & cross-instance delivery for the full contract.
Auth lockout looser than expected on a multi-replica gateway
Symptom: Magic-link or approval lockout lets through roughly N× more attempts than the documented max_attempts on an N-replica gateway.
Cause: push.redis is not configured, so each replica keeps its own auth rate-limit bucket.
Fix: Point every replica at the same Redis in gateway.push.redis — the same block the turn lock and idempotency store already share. If the log shows gateway.push.redis set but Redis auth rate limiter unavailable, install the redis package. See Cluster-Wide Auth Rate Limiting.
Reading the hello_error Envelope
When the gateway rejects a connection, it sends a structured hello_error frame before closing. Each (code, next_step) pair maps to a specific operator action.
code | next_step | Action |
|---|---|---|
rate_limited | wait_then_retry | Wait retry_after_seconds then reconnect; if persistent, raise the rate limiter ceiling |
origin_not_allowed | do_not_retry | Add the client origin to allowed_origins in gateway.yaml |
configuration_error | do_not_retry | External bind without allowed_origins configured; bind to loopback or set the allowlist |
auth_required | reauthenticate | Fetch a token (CLI or pairing flow) and reconnect |
protocol_unsupported | upgrade_client | Update the client SDK to a newer version |
protocol_unsupported | downgrade_client | Server is older than the client; pin the client to an older release or upgrade the server |
agent_not_found | do_not_retry | Fix the agent_id in the hello frame |
Example envelope received on rate-limit:
{
"type": "hello_error",
"code": "rate_limited",
"message": "Too many connection attempts",
"next_step": "wait_then_retry",
"retry_after_seconds": 30,
"next": "wait_then_retry"
}See Gateway Handshake Protocol for the full field reference and ConnectRecoveryStep values.
Authentication Errors
GatewayStartupError: Cannot bind to 0.0.0.0 without an auth token
Symptom: Gateway fails to start when binding to external interfaces without authentication.
- Use onboarding wizard
bash praisonai onboardThis automatically generates and saves a secure token.
- Or set token manually
bash export GATEWAY_AUTH_TOKEN=$(openssl rand -hex 16) praisonai gateway start --host 0.0.0.0
UIStartupError: Cannot bind to 0.0.0.0 with default admin/admin credentials
Symptom: Chainlit UI fails to start on external interface with default credentials.
- Set custom credentials
bash export CHAINLIT_USERNAME=myuser export CHAINLIT_PASSWORD=mypass praisonai chat --host 0.0.0.0 - Or allow defaults for demos (unsafe)
bash export PRAISONAI_ALLOW_DEFAULT_CREDS=1 praisonai chat --host 0.0.0.0
Gateway refuses to start: gateway.auth_token is weak/placeholder
Symptom: doctor or start refuses with “gateway.auth_token is a known-weak/placeholder value”.
Preview the repair, then apply it — --fix mints a strong token and re-validates:
- Preview (writes nothing, exits 1)
bash praisonai gateway doctor --config gateway.yaml --fix --dry-rungateway_auth_token: weak → would mint a strong token (--dry-run) - Apply (mints, persists, re-validates)
bash praisonai gateway doctor --config gateway.yaml --fixgateway_auth_token: weak → generated a strong token… done re-validated: gateway_auth_token now strong
An explicit weak auth_token in gateway.yaml is rewritten in place. ${ENV} references are left alone — they resolve from ~/.praisonai/.env, which --fix already updated. See Gateway CLI › Auto-repair.
My gateway logs show gw_****xxxx instead of the full token
This is intentional for security — tokens are fingerprinted in logs to prevent exposure.
- Retrieve full token from environment file
bash cat ~/.praisonai/.env | grep GATEWAY_AUTH_TOKEN - Or check environment variables
bash echo $GATEWAY_AUTH_TOKEN
Magic-link login works in WebSocket but fails over HTTP (or vice versa)
Symptom: One auth method works but the other fails, even with the same token.
Cause (pre-fix): HTTP/magic-link and WebSocket used different secret sources before PR #1744.
- Upgrade PraisonAI
Upgrade to PraisonAI ≥ v4.6.47 (ships PR #1744). Config token now exports to env, unifying all auth paths.
- Restart the gateway
bash praisonai gateway restartConfig token precedence is now enforced on restart.
Restart After Config Change
When you update bot configuration files, restart the daemon using these OS-specific commands (matching the onboard Done panel):
macOS
launchctl kickstart -k gui/$(id -u)/ai.praison.botLinux
systemctl --user restart praisonai-botWindows
schtasks /End /TN PraisonAIGateway && schtasks /Run /TN PraisonAIGatewayDiagnostic Commands
Quick commands for gathering diagnostic information:
# Full status check
praisonai gateway status
# Daemon-only check (for scripts)
praisonai gateway status --daemon-only
# Recent logs (last 50 lines)
praisonai gateway logs -n 50
# Check the PID lock file
cat ~/.praisonai/gateway-127_0_0_1-8765.pid
# Stop a running gateway
praisonai gateway stop
praisonai gateway stop --force
# Check port usage
lsof -i :8765
# Test health endpoint directly
curl -v http://127.0.0.1:8765/health
# Check PraisonAI version
praisonai --version
# Platform daemon status
# macOS: launchctl list | grep ai.praison
# Linux: systemctl --user status praisonai-bot
# Windows: schtasks /Query /TN PraisonAIGatewayPlatform-Specific Notes
macOS
LaunchAgent Path: ~/Library/LaunchAgents/ai.praison.bot.plist
Log Path: ~/.praisonai/logs/bot-stderr.log
# Manual management
launchctl load ~/Library/LaunchAgents/ai.praison.bot.plist
launchctl unload ~/Library/LaunchAgents/ai.praison.bot.plist
launchctl kickstart -k gui/$(id -u)/ai.praison.bot
# Check if loaded
launchctl list | grep ai.praisonLinux
Service Path: ~/.config/systemd/user/praisonai-bot.service
Logs: journalctl --user -u praisonai-bot
# Manual management
systemctl --user start praisonai-bot
systemctl --user stop praisonai-bot
systemctl --user restart praisonai-bot
systemctl --user enable praisonai-bot
# Check status
systemctl --user status praisonai-botWindows
Task Path: Task Scheduler → PraisonAIGateway
Logs: Windows Event Log
Requires APPDATA. The autostart installer uses %APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup (Startup-folder fallback) and a Scheduled Task wrapper script under the same folder. If APPDATA is unset (as in most non-Windows shells and some WSL contexts), install/uninstall refuse cleanly rather than write to a literal %APPDATA%\... path. See PR #4996.
# Manual management via Task Scheduler or:
schtasks /Run /TN PraisonAIGateway
schtasks /End /TN PraisonAIGateway
# Check status
schtasks /Query /TN PraisonAIGatewayConfig reload did not apply
Symptom: You edited gateway.yaml or sent SIGHUP, but channels or agents still run the old configuration.
| Check | What to look for |
|---|---|
| Log line | A successful reload logs a summary such as reload applied: agents; restart[telegram] — if absent, the watcher may not have fired or SIGHUP was ignored (Windows has no SIGHUP) |
| Drain window | Channel restarts wait up to gateway.reload_drain_timeout (falls back to drain_timeout) — a slow turn can delay the visible restart |
| Install | pip install "praisonai[gateway]" enables watchdog; without it, mtime polling (about 5 s) still reloads but more slowly |
See Gateway Config Reload for file-watch vs SIGHUP paths and YAML keys.
Multi-Channel Troubleshooting
Common failure modes when using multiple bots on the same platform:
| Symptom | Cause | Fix |
|---|---|---|
Token ${X} is used by multiple channels | Two channels reference the same env var in bot.yaml | Give each channel its own env var and create a separate bot in @BotFather |
Same bot token value is used by multiple channels | Two different env vars resolve to the same actual token | Generate a fresh token from @BotFather for the duplicate channel |
Channel '<x>' token '<env>' doesn't follow naming convention | Custom env var name | Rename to `PLATFORM_ |
_BOT_TOKEN (e.g. TELEGRAM_CFO_BOT_TOKEN) | | Missing token: <env> | Env var referenced in bot.yaml is unset | Add it to ~/.praisonai/.env` |
Example Fix:
# Problem: Both channels use the same token
# Error: "Token TELEGRAM_BOT_TOKEN is used by multiple channels"
# Solution: Create unique tokens per role
# 1. Create new bot in @BotFather for CFO role
# 2. Add unique environment variable
export TELEGRAM_CFO_BOT_TOKEN="987654321:DEF..."
# 3. Update bot.yaml
channels:
telegram_cfo:
platform: telegram
token: ${TELEGRAM_CFO_BOT_TOKEN} # Unique token
routes:
default: cfoValidation:
# Check multi-channel configuration
praisonai doctor multi_channel_tokens
# ✅ Expected output:
# "Multi-channel configuration looks good (N channels)"Group Policy Issues
Bot answers group @mentions with no context of the preceding conversation
You’re on group_policy: mention_only — unmentioned messages are dropped and leave no session record, so an @mention only sees its own text. Switch to group_policy: observe (Telegram) so the transcript retains unmentioned messages as passive context. Combine with session_scope: per_chat for shared group memory. Note that a reply to the bot is still admitted as an implicit mention, so the natural follow-up (tap Reply on the bot’s answer) works without re-typing @bot — see Implicit Mentions to disable this or enable quote/thread signals.
channels:
telegram:
platform: telegram
token: ${TELEGRAM_BOT_TOKEN}
group_policy: observe # keep unmentioned messages as context
session:
session_scope: per_chat # share that context across the groupChannel Supervision Issues
Channel goes silent but /health shows running: true
Symptom: Channel stops receiving messages but /health still reports "running": true.
Cause: Pre-PR-2041 behaviour, or the health: block is missing from gateway.yaml — hung sockets are not detected until an exception is raised.
Fix: Add the proactive health block:
gateway:
health:
interval: 300
stale_after: 120
enabled: trueSee Proactive Health Monitoring.
Channel keeps restarting every 5 minutes
Symptom: Channel restarts on a regular interval visible in logs.
Cause: stale_after too low for a quiet channel, or interval too aggressive for a slow remote API.
Fix: Raise stale_after to e.g. 600, or lower max_restarts_per_hour so the cap kicks in and surfaces the issue:
gateway:
health:
stale_after: 600
max_restarts_per_hour: 3Every channel restarts at once — fleet crash-loop breaker tripped
Symptom: One of:
- Log line
Fleet crash-loop breaker TRIPPED: holding channel restarts (...). praisonai gateway statusshowsfleet.breaker_tripped: true.list_degraded()/GET /healthshows agatewayowner withowner_id: "fleet".
Cause: A systemic upstream fault — a bad shared provider, a network partition, or an org-wide expired token — is restarting every channel at once. The fleet-level breaker tripped one aggregate breaker instead of letting each channel silently burn its own max_restarts_per_hour budget.
- Diagnose the shared cause
bash praisonai gateway doctor --config gateway.yamlLook for the shared provider / token / network issue behind the storm — a single fault is affecting all channels.
- Fix the underlying fault
Rotate the shared token, restore the provider, or heal the network partition. While the breaker is tripped, restarts are held on purpose — you do not need to restart the gateway.
- Wait one cooldown, then confirm recovery
After the cause is fixed, wait one
breaker_cooldown_s(default 120s). The breaker re-arms cleanly and thegateway/fleetdegraded entry clears on the next monitor sweep — no manual poll needed. Confirm with:bash curl http://127.0.0.1:8765/health | jq '.channels' # fleet owner should be gone
Channel Shows state: failed in /health
Symptom: When checking GET /health, a channel shows "state": "failed" with error details.
Common Causes:
- Telegram Conflict: Multiple bot instances using the same token
- Invalid Credentials: Bot token revoked or incorrect
- Permission Issues: Bot lacks required permissions
Investigation Steps:
- Check Error Details
bash curl http://127.0.0.1:8765/health | jq '.channels.telegram.supervision'Look for
last_errorandlast_error_timefields. - Telegram Conflict Resolution
If error contains “Conflict: terminated by other getUpdates”:
bash # Stop any other bot instances using the same token # Then force reconnect to reset state praisonai gateway reconnect telegram - Credential Verification
For invalid token errors, verify your bot token:
bash # Test token directly curl "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/getMe"
Channel Keeps Retrying Forever
Symptom: High total_recoveries count, constant retry attempts visible in logs.
Investigation:
# Check supervision status
curl http://127.0.0.1:8765/health | jq '.channels'
# Look for:
# - High total_recoveries value
# - next_retry_at timestamp
# - last_error detailsResolution:
# Temporarily pause while investigating
praisonai gateway pause telegram
# Investigate root cause (network, DNS, etc.)
# Fix underlying issue
# Resume when ready
praisonai gateway resume telegramConfig Migration
When praisonai doctor --only gateway_config_migration reports Config can be migrated, your YAML uses a legacy shape that loads correctly but can be rewritten to the canonical format.
- Detect migration opportunities
bash praisonai doctor --only gateway_config_migrationExample WARN output:
⚠ Gateway Config Migration [MEDIUM] Config can be migrated: 2 change(s) • telegram: allowed_users string → list migration available • Set telegram.group_policy to secure default 'mention_only' - Understand auto-normalisation
At load time,
GatewayConfigSchemaalready normalises legacy formats — your bot runs without rewriting the file. Persist the canonical form when you want the on-disk YAML to match what the schema produces. - Apply canonical YAML
Legacy shape Canonical form Top-level platform+tokenchannels:dict with one entryBotOS platforms:dictchannels:dict (same keys)allowed_users: "id1,id2"(string)allowed_users: ["id1", "id2"](list)See Gateway Config Migration for before/after YAML.
Environment Variables in Config
Gateway and bot configs support ${VAR} substitution in any string value. Resolution order:
- Process environment variables
~/.praisonai/.env(loaded automatically; override path withPRAISONAI_ENV_FILE)
# Verify all referenced variables resolve
praisonai doctor --only gateway_env_substitutionUnset variables cause validation to FAIL at load time and in the gateway_env_substitution doctor check.
Best Practices
Use praisonai gateway status first
Always run praisonai gateway status before diving into logs – it shows port, PID, and daemon state in one command.
Stop before restart
Always use praisonai gateway stop before restarting – this drains active sessions and prevents data loss.
Use onboard for fresh installs
When in doubt, run praisonai onboard – it handles daemon setup, credentials, and port configuration automatically.
Check logs for crash loops
If bot-stderr.log grows rapidly, you have a crash loop – stop the daemon, upgrade PraisonAI, then restart.