Skip to content

Troubleshooting

Common issues and how to resolve them.

WebSocket Connection Fails

Symptom: The widget never connects, or client.connectionState stays at "connecting".

Cause: Wrong WebSocket endpoint protocol or URL.

Fix:

  • Use wss:// when your server is behind TLS (HTTPS). Use ws:// only for local development.
  • Ensure the endpoint URL points to the root path of the Pulse server (e.g., wss://pulse.yourdomain.com), not to /api/v1 or any sub-path.
  • If using a reverse proxy, confirm it is configured to pass WebSocket upgrade headers (Upgrade and Connection).
html
<!-- Local development -->
<pulse-widget endpoint="ws://localhost:4567" ...></pulse-widget>

<!-- Production (behind TLS) -->
<pulse-widget endpoint="wss://pulse.yourdomain.com" ...></pulse-widget>

Expired JWT Token

Symptom: The server sends an auth:error message, or the widget shows a connection error after working previously.

Cause: The user token issued by /auth/token has expired.

Fix:

  • Tokens are short-lived by design. Your backend should mint a fresh token each time the user loads the page.
  • Do not cache tokens on the client for extended periods. Fetch a new token on each page load or when re-initializing the widget.
javascript
// Always fetch a fresh token before initializing
const res = await fetch('/api/collab-token');
const { token } = await res.json();

const widget = document.createElement('pulse-widget');
widget.setAttribute('token', token);
// ...

CORS Errors

Symptom: Browser console shows Access-Control-Allow-Origin errors when the widget tries to upload a file or when calling the REST API.

Cause: The Pulse server's ALLOWED_ORIGINS environment variable does not include your frontend's origin.

Fix:

  • Set ALLOWED_ORIGINS to a comma-separated list of your frontend origins:
bash
ALLOWED_ORIGINS=https://yourdomain.com,https://app.yourdomain.com
  • During development, you can omit ALLOWED_ORIGINS (defaults to allowing all origins), but always restrict it in production.
  • Make sure the origin includes the protocol (https://) and does not include a trailing slash.

Rate Limiting (429 Responses)

Symptom: API requests return 429 Too Many Requests.

Cause: You've exceeded the rate limit of 100 requests per minute per IP address (or 5/min for the admin login endpoint).

Fix:

  • Add backoff/retry logic in your integration code. Wait and retry after the rate limit window resets.
  • If you're making bulk API calls from a server, throttle your requests to stay under the limit.
  • Requests from 127.0.0.1 and ::1 (localhost) are excluded from rate limiting.

File Upload Fails

Symptom: Uploading a file returns an error (400, 403, or 413).

Common causes and fixes:

StatusMessageFix
400"No file provided"Ensure the request sends a file field in multipart/form-data
400"Unsupported file type"Only JPEG, PNG, GIF, WebP images; WebM, OGG, MP4, MPEG, WAV audio; and WebM, MP4 video are supported
403"Image/Audio/Video uploads are disabled"Enable the media type in Environment Config via the admin panel
413"File too large"The file exceeds maxFileSizeMb (default 10 MB). Increase the limit in environment config, or reduce the file size

Missing Cursors or Presence

Symptom: Users don't see each other's cursors or presence avatars.

Fix:

  • Confirm both users are connected to the same room (the room attribute must match exactly).
  • Check that showCursors and showPresence are enabled in your Environment Config.
  • Users appear offline after 60 seconds of no heartbeat. If a user's tab is suspended by the browser, they may drop from presence.

Data Not Syncing Across Instances

Symptom: Users on different server instances don't see each other's changes in real time.

Cause: Redis is not configured for pub/sub across instances.

Fix:

  • Set the REDIS_URL environment variable so all instances share a Redis pub/sub channel. See the Deployment guide for details.

Admin Panel Not Loading

Symptom: Navigating to /panel shows a blank page or 404.

Cause: The admin panel static files are not built or not in the expected location.

Fix:

  • Run the full build so the admin panel assets are generated.
  • The server expects the admin dist at packages/admin/dist relative to the server source. If using Docker, the Dockerfile handles this automatically.

Pulse Collaboration SDK