mastra-ai/mastra · critical
SlackIntegration: 'signingSecret' is required — Slack cannot
Error message
SlackIntegration: 'signingSecret' is required — Slack cannot verify inbound requests without it.
What it means
The SlackIntegration constructor requires `config.signingSecret` because Slack sends signed requests (x-slack-signature header) that must be verified with the app's Signing Secret from the Slack app settings. Without it the integration cannot authenticate that inbound HTTP requests genuinely come from Slack, so it refuses to construct rather than serving an insecure endpoint.
Source
Thrown at mastracode/factory/src/integrations/slack/integration.ts:119
readonly id = 'slack';
/**
* The OIDC connect flow round-trips a signed `state` through Slack, so the
* replica handling the callback must be able to verify a state a different
* replica signed.
*/
readonly requiresStableStateSigner = true;
readonly #config: SlackIntegrationConfig;
/**
* Whether `channels()` found a source-control owner on the context and wired
* repo-backed sessions. Set at the channels() attach path, which runs once at
* boot before diagnostics are served.
*/
#repoBackedSessions = false;
constructor(config: SlackIntegrationConfig) {
if (!config.signingSecret) {
throw new Error(
"SlackIntegration: 'signingSecret' is required — Slack cannot verify inbound requests without it.",
);
}
this.#config = config;
}
channels(ctx: IntegrationContext): FactoryChannelsConfig {
// Repo-backed sessions come from the factory's source-control owner
// (GitHub, when registered) — no config-level wiring by the entry.
const sourceControlOwner = ctx.storage.sourceControlOwner;
this.#repoBackedSessions = Boolean(sourceControlOwner);
return createSlackChannelsConfig({
slack: {
clientId: this.#config.clientId,
clientSecret: this.#config.clientSecret,
signingSecret: this.#config.signingSecret,
botToken: this.#config.botToken,
},View on GitHub (pinned to 75dd419e61)
Solutions
- Copy the Signing Secret from Slack app settings → Basic Information → App Credentials and pass it as `signingSecret`.
- Set the SLACK_SIGNING_SECRET env var in the deployment environment (not just locally).
- Add a boot-time check that fails with a clear message if the env var is empty before constructing the integration.
- Do not substitute the Bot Token (xoxb-...) — the Signing Secret is a separate credential.
Example fix
// before
new SlackIntegration({ signingSecret: process.env.SLACK_SIGNING_SECRET, ... }); // env unset => undefined
// after
const signingSecret = process.env.SLACK_SIGNING_SECRET;
if (!signingSecret) throw new Error('SLACK_SIGNING_SECRET is not set');
new SlackIntegration({ signingSecret, ... }); Defensive patterns
Strategy: validation
Validate before calling
const signingSecret = process.env.SLACK_SIGNING_SECRET;
if (!signingSecret) {
throw new Error('SLACK_SIGNING_SECRET env var is missing; copy it from Slack app settings → Basic Information.');
}
new SlackIntegration({ signingSecret, ... }); Type guard
function hasSigningSecret(c: SlackIntegrationConfig): c is SlackIntegrationConfig & { signingSecret: string } {
return typeof c.signingSecret === 'string' && c.signingSecret.length > 0;
} Try / catch
let integration: SlackIntegration;
try {
integration = new SlackIntegration(config);
} catch (err) {
if (err instanceof Error && err.message.includes("'signingSecret' is required")) {
console.error('Boot failed: provision SLACK_SIGNING_SECRET before starting.');
process.exit(1);
}
throw err;
} Prevention
- Fail at process startup if SLACK_SIGNING_SECRET is absent, before any construction.
- Keep the Signing Secret and Bot Token in separate, clearly named env vars.
- Add the var to deployment/secret-manager checklists for every environment.
When it happens
Trigger: Calling `new SlackIntegration(config)` with `signingSecret` undefined, null, or an empty string — typically when it is read from env (`process.env.SLACK_SIGNING_SECRET`) and that variable is unset or blank.
Common situations: Deploying to an environment where the secret was never provisioned (missing .env, secrets manager not mounted); renaming the env var in code but not in the deployment; copying config from a Slack app where only the Bot Token was configured.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- Google Workspace Directory authentication is not configured.
- [Slack] Failed to resolve Mastra storage. Ensure your Mastra
- [Slack] No storage available. SlackProvider requires persist
- No Slack installation found for agent "${agentId}"
- SlackProvider is not configured. Provide a refreshToken via
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/f14c33e7672747ce.
Report an issue: GitHub.