rohitg00/ai-engineering-from-scratch · error · Error

SLACK_SIGNING_SECRET is required

Error message

SLACK_SIGNING_SECRET is required

What it means

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.

Solutions

  1. Export SLACK_SIGNING_SECRET in the deployment environment before starting the server
  2. Pass options.signingSecret explicitly (the intended path in tests and local demos)
  3. Fail fast at process start with a clear config checklist instead of crashing on the first request
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at phases/19-capstone-projects/06-devops-troubleshooting-agent/code/ts/src/server.ts:32 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of rohitg00/ai-engineering-from-scratch@39ea8a1c6d (2026-08-26). Data as JSON: /api/errors/18ae29f48fbea463. Report an issue: GitHub.

Appendix: source

Thrown at phases/19-capstone-projects/06-devops-troubleshooting-agent/code/ts/src/server.ts:32

      }),
    )
    .optional(),
  response_url: z.string().optional(),
});

export type AppOptions = {
  signingSecret?: string;
  outboundLog?: OutboundCall[];
  now?: () => number;
};

export function buildApp(options: AppOptions = {}): {
  app: Hono;
  outboundLog: OutboundCall[];
} {
  const signingSecret = options.signingSecret || process.env.SLACK_SIGNING_SECRET;
  if (!signingSecret) {
    throw new Error("SLACK_SIGNING_SECRET is required");
  }
  const outboundLog: OutboundCall[] = options.outboundLog ?? [];
  const now = options.now ?? (() => Math.floor(Date.now() / 1000));
  const app = new Hono();

  app.get("/health", (c) => c.json({ ok: true, outboundCount: outboundLog.length }));

  app.post("/slack/command", async (c) => {
    const rawBody = await c.req.text();
    const timestamp = c.req.header("x-slack-request-timestamp") ?? "";
    const signature = c.req.header("x-slack-signature") ?? "";
    const verdict = verifySlackSignature({
      signingSecret,
      timestamp,
      signature,
      rawBody,
      nowSeconds: now(),
    });

View on GitHub (pinned to 39ea8a1c6d)