calcom/cal.diy · error · Error
Unhandled values
Error message
Unhandled values
What it means
Thrown by the example credential-sync getToken endpoint when req.body.appSlug is neither 'google-calendar' nor 'zoom'. This is example/demo code showing how to build a credential sync server; it only implements two providers. The error is caught and returned as a 500 JSON body.
Source
Thrown at example-apps/credential-sync/pages/api/getToken.ts:29
return res.status(403).json({ message: "secret header not set" });
}
if (secret !== CALCOM_CREDENTIAL_SYNC_SECRET) {
return res.status(403).json({ message: "Invalid secret" });
}
const calcomUserId = req.body.calcomUserId;
const appSlug = req.body.appSlug;
console.log("getToken Params", {
calcomUserId,
appSlug,
});
let accessToken;
if (appSlug === "google-calendar") {
accessToken = await generateGoogleCalendarAccessToken();
} else if (appSlug === "zoom") {
accessToken = await generateZoomAccessToken();
} else {
throw new Error("Unhandled values");
}
if (!accessToken) {
throw new Error("Unable to generate token");
}
res.status(200).json({
_1: true,
access_token: accessToken,
});
} catch (e) {
res.status(500).json({ error: e.message });
}
}
View on GitHub (pinned to 176037d0af)
Solutions
- Add a branch for the new appSlug with its token-generation function in getToken.ts and the shared integrations lib.
- Ensure the request body includes appSlug matching one of the supported values.
- Copy this pattern into a real server and implement the providers you actually use.
Example fix
// before
if (appSlug === 'google-calendar') { ... }
else if (appSlug === 'zoom') { ... }
else { throw new Error('Unhandled values'); }
// after
const generators: Record<string, () => Promise<string>> = {
'google-calendar': generateGoogleCalendarAccessToken,
'zoom': generateZoomAccessToken,
'microsoft-teams': generateTeamsAccessToken,
};
const gen = generators[appSlug];
if (!gen) throw new Error(`Unhandled appSlug: ${appSlug}`);
accessToken = await gen(); Defensive patterns
Strategy: validation
Validate before calling
const supported = ['google-calendar', 'zoom'];
if (!supported.includes(appSlug)) {
return res.status(400).json({ error: `Unsupported appSlug '${appSlug}'. Supported: ${supported.join(', ')}` });
} Type guard
const SUPPORTED_SLUGS = ['google-calendar', 'zoom'] as const;
type SupportedSlug = typeof SUPPORTED_SLUGS[number];
function isSupportedSlug(s: unknown): s is SupportedSlug {
return typeof s === 'string' && (SUPPORTED_SLUGS as readonly string[]).includes(s);
} Try / catch
null
Prevention
- Validate appSlug against an explicit allowlist before branching.
- When adding a provider, extend the allowlist and generator map together.
- Return a descriptive error listing supported slugs for the caller.
When it happens
Trigger: POST to /api/getToken in the example credential-sync app with appSlug set to any value other than 'google-calendar' or 'zoom' (e.g. 'outlook', 'stripe', or undefined).
Common situations: Extending credential sync to a new provider without adding a branch; appSlug missing from the request body; typo in the slug; Cal.com requesting a token for an app the example server does not yet support.
Related errors
- Unable to generate token
- Unhandled appSlug: ${appSlug}
- Invalid refreshed tokens were returned
- Invalid conferencing app, available apps are:
- OAuth client with ID '${clientId}' not found
AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12).
Data as JSON: /api/errors/bba05c765bf7fb82.
Report an issue: GitHub.