{"record":{"id":"cfd75c4410c9aaf7","repo":"ComposioHQ/composio","slug":"function-is-required-for-trigger-subscription","errorCode":null,"errorMessage":"Function is required for trigger subscription","messagePattern":"Function is required for trigger subscription","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ts/packages/core/src/models/Triggers.ts","lineNumber":613,"sourceCode":"  /**\n   * Subscribe to all the triggers\n   *\n   * @param fn - The function to call when a trigger is received\n   * @param filters - The filters to apply to the triggers\n   *\n   * @example\n   * ```ts\n   *\n   * triggers.subscribe((data) => {\n   *   console.log(data);\n   * }, );\n   * ```\n   */\n  async subscribe(\n    fn: (_data: IncomingTriggerPayload) => void,\n    filters: TriggerSubscribeParams = {}\n  ) {\n    if (!fn) throw new Error('Function is required for trigger subscription');\n\n    const parsedFilters = TriggerSubscribeParamSchema.safeParse(filters);\n\n    if (!parsedFilters.success) {\n      throw new ValidationError(`Invalid parameters passed to subscribe to triggers`, {\n        cause: parsedFilters.error,\n      });\n    }\n\n    logger.debug('🔄 Subscribing to triggers with filters: ', JSON.stringify(filters, null, 2));\n    await this.pusherService.subscribe((_data: Record<string, unknown>) => {\n      logger.debug('Received raw trigger data', JSON.stringify(_data, null, 2));\n\n      // Parse using unified method that handles V1/V2/V3 and legacy formats\n      const parsedData = this.parsePusherPayload(_data);\n\n      if (this.shouldSendTriggerAfterFilters(parsedFilters.data, parsedData)) {\n        try {","sourceCodeStart":595,"sourceCodeEnd":631,"githubUrl":"https://github.com/ComposioHQ/composio/blob/64b1b85502b1beeb2379e6c9e8bf1104504fa637/ts/packages/core/src/models/Triggers.ts#L595-L631","documentation":"Plain Error('Function is required for trigger subscription') is thrown by Triggers.subscribe when the fn callback is falsy. subscribe delivers incoming trigger payloads by invoking fn, so a missing handler is rejected immediately. Note this is a generic Error (not ValidationError); the filters object is validated separately afterwards via TriggerSubscribeParamSchema.","triggerScenarios":"Calling triggers.subscribe(undefined, filters), subscribe(null), or otherwise passing a falsy first argument — e.g. wrong argument order putting filters first.","commonSituations":"Refactors dropping the callback argument; conditional handler construction ending up undefined; passing filters as the first parameter.","solutions":["Pass a function as the first argument: triggers.subscribe((data) => {...}, filters)","Check argument order — fn comes before filters","If the handler is optional in your code, default it to a no-op logger instead of undefined"],"exampleFix":"// before\ntriggers.subscribe(undefined, { triggerSlugs: ['github_issue_opened'] });\n\n// after\ntriggers.subscribe(\n  (data) => console.log('trigger fired', data),\n  { triggerSlugs: ['github_issue_opened'] }\n);","handlingStrategy":"type-guard","validationCode":"const handler = onTrigger ?? ((data: unknown) => console.warn('trigger fired, no handler', data));\nif (typeof handler !== 'function') throw new Error('subscribe requires a function handler');\ntriggers.subscribe(handler, filters);","typeGuard":"const isTriggerHandler = (fn: unknown): fn is (data: unknown) => void =>\n  typeof fn === 'function';","tryCatchPattern":"try {\n  triggers.subscribe(fn, filters);\n} catch (e) {\n  if (e instanceof Error && /Function is required/.test(e.message)) {\n    // supply a default handler and retry\n  }\n}","preventionTips":["Always pass an explicit callback; fn comes before filters","Default optional handlers to a no-op logger rather than undefined","Type the call site so a non-function first arg fails at compile time"],"tags":["composio","triggers","subscribe","callback","typescript"],"backgroundTag":"missing-callback-handler","analyzedSha":"64b1b85502b1beeb2379e6c9e8bf1104504fa637","analyzedAt":"2026-08-28T15:39:33.623Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}