{"record":{"id":"18ae29f48fbea463","repo":"rohitg00/ai-engineering-from-scratch","slug":"slack-signing-secret-is-required","errorCode":null,"errorMessage":"SLACK_SIGNING_SECRET is required","messagePattern":"SLACK_SIGNING_SECRET is required","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"phases/19-capstone-projects/06-devops-troubleshooting-agent/code/ts/src/server.ts","lineNumber":32,"sourceCode":"      }),\n    )\n    .optional(),\n  response_url: z.string().optional(),\n});\n\nexport type AppOptions = {\n  signingSecret?: string;\n  outboundLog?: OutboundCall[];\n  now?: () => number;\n};\n\nexport function buildApp(options: AppOptions = {}): {\n  app: Hono;\n  outboundLog: OutboundCall[];\n} {\n  const signingSecret = options.signingSecret || process.env.SLACK_SIGNING_SECRET;\n  if (!signingSecret) {\n    throw new Error(\"SLACK_SIGNING_SECRET is required\");\n  }\n  const outboundLog: OutboundCall[] = options.outboundLog ?? [];\n  const now = options.now ?? (() => Math.floor(Date.now() / 1000));\n  const app = new Hono();\n\n  app.get(\"/health\", (c) => c.json({ ok: true, outboundCount: outboundLog.length }));\n\n  app.post(\"/slack/command\", async (c) => {\n    const rawBody = await c.req.text();\n    const timestamp = c.req.header(\"x-slack-request-timestamp\") ?? \"\";\n    const signature = c.req.header(\"x-slack-signature\") ?? \"\";\n    const verdict = verifySlackSignature({\n      signingSecret,\n      timestamp,\n      signature,\n      rawBody,\n      nowSeconds: now(),\n    });","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/rohitg00/ai-engineering-from-scratch/blob/39ea8a1c6d0b61f071226eff7ede4d4105fed820/phases/19-capstone-projects/06-devops-troubleshooting-agent/code/ts/src/server.ts#L14-L50","documentation":"Startup configuration guard in buildApp: neither options.signingSecret nor the SLACK_SIGNING_SECRET environment variable was provided, so the app has no key to verify Slack request signatures and cannot safely accept traffic. It fires at construction time, before any request is served.","triggerScenarios":"Thrown at phases/19-capstone-projects/06-devops-troubleshooting-agent/code/ts/src/server.ts:32 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Export SLACK_SIGNING_SECRET in the deployment environment before starting the server","Pass options.signingSecret explicitly (the intended path in tests and local demos)","Fail fast at process start with a clear config checklist instead of crashing on the first request"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"39ea8a1c6d0b61f071226eff7ede4d4105fed820","analyzedAt":"2026-08-26T03:13:46.626Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}