ComposioHQ/composio · error · ComposioWebhookSignatureVerificationError

No webhook ID was provided. Please pass the value of the 'we

Error message

No webhook ID was provided. Please pass the value of the 'webhook-id' header.

What it means

Thrown by Composio's webhook signature verification when the 'webhook-id' header is missing or empty. Verification requires the webhook ID (msgId) because it is part of the signed payload (msgId.timestamp.payload), so without it the HMAC cannot be computed. The library throws ComposioWebhookSignatureVerificationError instead of silently accepting an unverifiable request.

Source

Thrown at ts/packages/core/src/models/Triggers.ts:1247

  ): Promise<void> {
    if (payload.length === 0) {
      throw new ComposioWebhookSignatureVerificationError('No webhook payload was provided.');
    }

    if (signature.length === 0) {
      throw new ComposioWebhookSignatureVerificationError(
        "No signature header value was provided. Please pass the value of the 'webhook-signature' header."
      );
    }

    if (secret.length === 0) {
      throw new ComposioWebhookSignatureVerificationError(
        'No webhook secret was provided. You can find your webhook secret in your Composio dashboard.'
      );
    }

    if (webhookId.length === 0) {
      throw new ComposioWebhookSignatureVerificationError(
        "No webhook ID was provided. Please pass the value of the 'webhook-id' header."
      );
    }

    if (webhookTimestamp.length === 0) {
      throw new ComposioWebhookSignatureVerificationError(
        "No webhook timestamp was provided. Please pass the value of the 'webhook-timestamp' header."
      );
    }

    // Parse signature - may have multiple signatures prefixed with version (e.g., "v1,base64sig")
    const signatures = signature.split(' ');
    const v1Signatures: string[] = [];

    for (const sig of signatures) {
      const [version, value] = sig.split(',');
      if (version === 'v1' && value) {
        v1Signatures.push(value);

View on GitHub (pinned to 64b1b85502)

Solutions

  1. Forward the exact 'webhook-id' header from the webhook request into the verification call's webhookId option
  2. Check that your proxy/gateway does not strip custom webhook-* headers
  3. Log all incoming webhook-* headers in a debug route to confirm what arrives
  4. Ensure test harnesses send all three headers: webhook-id, webhook-timestamp, webhook-signature

Example fix

// before
await composio.triggers.verifyWebhookSignature(rawBody, sig, { secret, webhookId: req.headers['webhook_id'] ?? '', webhookTimestamp: req.headers['webhook-timestamp'] });
// after
await composio.triggers.verifyWebhookSignature(rawBody, sig, {
  secret,
  webhookId: req.headers['webhook-id'] as string,
  webhookTimestamp: req.headers['webhook-timestamp'] as string,
});
Defensive patterns

Strategy: validation

Validate before calling

const h = req.headers;
if (!h['webhook-id'] || !h['webhook-timestamp'] || !h['webhook-signature']) {
  return res.status(400).send('Missing webhook headers');
}

Type guard

const hasWebhookHeaders = (h: Record<string, unknown>): boolean =>
  typeof h['webhook-id'] === 'string' && (h['webhook-id'] as string).length > 0;

Try / catch

try { verifyWebhookSignature(...); } catch (e) { if (e instanceof ComposioWebhookSignatureVerificationError) return res.status(400).end(); throw e; }

Prevention

When it happens

Trigger: Calling composio.triggers.verifyWebhookSignature(payload, signatureHeader, {secret, webhookId, webhookTimestamp}) (or a verify/tolerate API that reads request headers) where webhookId is '' — typically because the 'webhook-id' header was not forwarded from the incoming request to the verification call.

Common situations: Frameworks that strip or rename custom headers (proxies, API gateways, AWS API Gateway header normalization), passing headers in the wrong order or with wrong names, or test code that only supplies 'webhook-signature' and 'webhook-timestamp'.

Related errors


AI-assisted analysis of ComposioHQ/composio@64b1b85502 (2026-08-28). Data as JSON: /api/errors/cdda0d1aa0eea288. Report an issue: GitHub.