ComposioHQ/composio · error · PusherSubscriptionError
Trigger subscription error
Error message
Trigger subscription error
What it means
Pusher emits pusher:subscription_error on a private channel when authorization fails or the channel cannot be joined. The SDK translates it into a PusherSubscriptionError('Trigger subscription error') with the underlying cause attached. For Composio, auth is done via your API key against {baseURL}/api/v3/internal/sdk/realtime/auth.
Source
Thrown at ts/packages/core/src/utils/pusher.ts:243
* @example
* ```ts
* composio.trigger.subscribe((data) => {
* console.log(data);
* });
* ```
*/
static triggerSubscribe(clientId: string, fn: (data: TriggerData) => void): void {
try {
if (!PusherUtils.pusherClient) {
throw new Error('Pusher client not initialized');
}
const channel = PusherUtils.pusherClient.subscribe(`private-${clientId}_triggers`);
// Add subscription error handling
channel.bind('pusher:subscription_error', (data: Record<string, unknown>) => {
const error = data.error ? String(data.error) : 'Unknown subscription error';
throw new PusherSubscriptionError(`Trigger subscription error`, {
cause: error,
});
});
// Wrap the callback to handle errors
const safeCallback = (data: TriggerData) => {
try {
fn(data);
} catch (error: unknown) {
const errorMessage = error instanceof Error ? error.message : String(error);
logger.error('Error in trigger callback:', errorMessage);
// Don't throw here to prevent breaking the subscription
}
};
PusherUtils.bindWithChunking(
channel as PusherClient,
'trigger_to_client',View on GitHub (pinned to 64b1b85502)
Solutions
- Verify your Composio API key is valid and belongs to the same workspace as the clientId
- Confirm baseURL matches the environment the clientId was created in
- Inspect logger.debug output of the auth response body for the backend's rejection reason
- Re-create the trigger/clientId if it was invalidated (e.g. deleted integration)
Defensive patterns
Strategy: try-catch
Validate before calling
// validate auth prerequisites before subscribing
if (!apiKey || !baseURL) throw new Error('Missing API credentials for realtime auth'); Type guard
const isPusherSubscriptionError = (e: unknown): boolean => e instanceof Error && e.constructor.name === 'PusherSubscriptionError';
Try / catch
try {
PusherUtils.triggerSubscribe(clientId, fn);
} catch (e) {
if (isPusherSubscriptionError(e) && e.cause) {
logger.error('Auth rejected:', e.cause);
// rotate key or fix baseURL/clientId
}
} Prevention
- Keep API key and clientId from the same workspace/environment
- Enable debug logging to capture the auth response body
- Re-create triggers after rotating keys or switching baseURL
When it happens
Trigger: Subscribing to private-{clientId}_triggers when the channel authorization POST fails: invalid/expired API key, wrong baseURL, network failure to the auth endpoint, or the backend rejecting the clientId.
Common situations: Expired or revoked Composio API key; pointing the SDK at the wrong environment/baseURL; clientId from a different workspace/project than the API key; auth endpoint returning non-JSON (proxy/HTML error page).
Related errors
- Pusher connection error: ${err.message}
- Invalid chunked trigger data format
- Failed to bind chunked events: ${errorMessage}
- Failed to subscribe to triggers: ${errorMessage}
- Failed to initialize Pusher client: ${errorMessage}
AI-assisted analysis of ComposioHQ/composio@64b1b85502 (2026-08-28).
Data as JSON: /api/errors/1d2b3a030c801a1a.
Report an issue: GitHub.