calcom/cal.diy · error · HttpError
Missing Giphy api_key
Error message
Missing Giphy api_key
What it means
Thrown by `checkGiphyApiKey` when the `api_key` field on the Giphy app's stored keys is not a string. Keys come from `getAppKeysFromSlug("giphy")`, which reads `app.keys` off the `App` row (returning `{}` when absent). If admins never configured a key, or stored it as a non-string JSON value, this fires as `HttpError` **400**. It guards every Giphy API call (`searchGiphy`, `getGiphyById`).
Source
Thrown at packages/app-store/giphy/lib/giphyManager.ts:8
import { HttpError } from "@calcom/lib/http-error";
import getAppKeysFromSlug from "../../_utils/getAppKeysFromSlug";
const checkGiphyApiKey = async () => {
const appKeys = await getAppKeysFromSlug("giphy");
if (typeof appKeys.api_key === "string") return appKeys.api_key;
throw new HttpError({ statusCode: 400, message: "Missing Giphy api_key" });
};
export const searchGiphy = async (locale: string, keyword: string, offset = 0) => {
const apiKey = await checkGiphyApiKey();
const queryParams = new URLSearchParams({
api_key: apiKey,
q: keyword,
limit: "1",
offset: String(offset),
// Contains images that are broadly accepted as appropriate and commonly witnessed by people in a public environment.
rating: "g",
lang: locale,
});
const response = await fetch(`https://api.giphy.com/v1/gifs/search?${queryParams.toString()}`, {
method: "GET",
headers: {
Accept: "application/json",
},View on GitHub (pinned to 176037d0af)
Solutions
- In the admin app-store settings for Giphy, set `api_key` to a valid Giphy API key string and save, then verify the `App` row's `keys` JSON contains `"api_key": "<string>"`.
- Add a UI preflight: fetch the Giphy app keys and disable/hide the GIF picker when `api_key` is missing so users never reach the 400.
- Tighten the guard to also reject blank strings (`!key.trim()`) so a whitespace-only value is treated as missing.
Example fix
// before
const checkGiphyApiKey = async () => {
const appKeys = await getAppKeysFromSlug("giphy");
if (typeof appKeys.api_key === "string") return appKeys.api_key;
throw new HttpError({ statusCode: 400, message: "Missing Giphy api_key" });
};
// after
const checkGiphyApiKey = async () => {
const appKeys = await getAppKeysFromSlug("giphy");
const key = typeof appKeys.api_key === "string" ? appKeys.api_key.trim() : "";
if (key) return appKeys.api_key as string;
throw new HttpError({ statusCode: 400, message: "Missing Giphy api_key" });
}; Defensive patterns
Strategy: validation
Validate before calling
// Check the configured key before invoking any Giphy manager function
import getAppKeysFromSlug from "@calcom/app-store/_utils/getAppKeysFromSlug";
async function getGiphyApiKeyOrNull() {
const keys = await getAppKeysFromSlug("giphy");
return typeof keys.api_key === "string" && keys.api_key.trim() ? (keys.api_key as string) : null;
}
// usage: skip the GIF picker when null
const apiKey = await getGiphyApiKeyOrNull();
if (!apiKey) { /* hide/disable GIF picker, do not call searchGiphy */ } Type guard
function hasGiphyApiKey(keys: Record<string, unknown>): keys is { api_key: string } {
return typeof keys.api_key === "string" && (keys.api_key as string).trim().length > 0;
} Prevention
- Configure the Giphy api_key in the app-store admin settings before enabling the GIF picker UI.
- Gate the feature behind a preflight key check so users never hit the 400.
- Store the key as a flat string in App.keys, never as a nested object or number.
When it happens
Trigger: Calling `searchGiphy(locale, keyword, offset)` or `getGiphyById(giphyId)` — i.e. the GIF picker in the event/booking UI — when the Giphy app's `api_key` is unset, empty (but non-string-typed), or stored as an object/number in the app-store admin settings (`App.keys` JSON).
Common situations: Fresh deployment where the admin never entered a Giphy key; key was put in an env var instead of the app-store settings UI; `App` row seeded without keys; key saved as a JSON object `{ api_key: { ... } }` by mistake.
Related errors
- Stripe app not found
- Already installed
- Unable to create user credential for giphy
- Session user must have an email
- `code` must be a string
AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12).
Data as JSON: /api/errors/a76b5222ac1b7ef9.
Report an issue: GitHub.