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

  1. Add a branch for the new appSlug with its token-generation function in getToken.ts and the shared integrations lib.
  2. Ensure the request body includes appSlug matching one of the supported values.
  3. 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

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


AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12). Data as JSON: /api/errors/bba05c765bf7fb82. Report an issue: GitHub.