calcom/cal.diy · error · Error
Error refreshing dub token: ${res?.error?.message ?? respons
Error message
Error refreshing dub token: ${res?.error?.message ?? response.statusText} What it means
Thrown inside Dub AnalyticsService.refreshAccessToken when Dub's token-refresh endpoint returns a non-2xx response. The handler reads the JSON body, marks the stored Cal.com credential invalid on HTTP 401 (so the user must re-authenticate), then throws an Error whose message interpolates Dub's error.message (or response.statusText as fallback).
Source
Thrown at packages/app-store/dub/lib/AnalyticsService.ts:87
grant_type: "refresh_token",
refresh_token: refreshToken,
}).toString(),
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
});
if (!response.ok) {
const res = await response.json();
if (response.status === 401) {
await CredentialRepository.updateCredentialById({
id: this.credential.id,
data: {
invalid: true,
},
});
}
throw new Error(`Error refreshing dub token: ${res?.error?.message ?? response.statusText}`);
}
return await response.json();
},
"dub",
this.credential.userId
);
newToken.expiry_date = Date.now() + newToken.expires_in * 1000;
await CredentialRepository.updateCredentialById({
id: this.credential.id,
data: { key: newToken as any },
});
return newToken;
} catch (err) {
this.log.error(err);
throw err;View on GitHub (pinned to 176037d0af)
Solutions
- On 401, prompt the user to reinstall the Dub integration (the credential is already flagged invalid by the handler).
- Verify the Dub app's client_id and client_secret in /apps/dub keys are current.
- For 429/5xx, retry with exponential backoff before surfacing failure.
- Confirm refresh_token was the most recent one returned by Dub (using a stale token after a refresh produces this error).
Example fix
// before
throw new Error(`Error refreshing dub token: ${res?.error?.message ?? response.statusText}`);
// after - typed error so callers can branch
if (response.status === 401) {
throw new DubTokenInvalidError(`Dub refresh failed: ${res?.error?.message ?? response.statusText}`, { credentialId: this.credential.id });
}
throw new Error(`Error refreshing dub token: ${res?.error?.message ?? response.statusText}`, { cause: res }); Defensive patterns
Strategy: try-catch
Validate before calling
if (!token?.refresh_token) throw new Error("No Dub refresh token stored; reinstall Dub integration."); Type guard
const isDubToken = (t: unknown): t is { access_token: string; refresh_token: string; expires_in: number } =>
typeof t === "object" && t !== null &&
typeof (t as any).access_token === "string" &&
typeof (t as any).refresh_token === "string"; Try / catch
try {
await analyticsService.sendEvent(...);
} catch (err) {
if (err instanceof Error && /refreshing dub token/i.test(err.message)) {
// credential was flagged invalid on 401; prompt reinstall
await notifyUserReconnectDub(credentialId);
return; // analytics is non-critical
}
throw err;
} Prevention
- Refresh Dub tokens proactively before expiry_date rather than on-demand.
- Treat Dub analytics as non-blocking so a token failure does not break bookings.
- Rotate Dub client_secret and update app keys atomically.
When it happens
Trigger: POST https://api.dub.co/oauth/token with grant_type=refresh_token returns non-2xx: refresh_token expired/revoked (401), client_secret wrong (401), rate limited (429), or Dub API outage (5xx).
Common situations: Dub refresh token older than 30 days (Dub tokens expire); user revoked Cal.com access in Dub; client_secret rotated but app keys not updated; Dub API rate limit; transient Dub 5xx.
Related errors
- Invalid google OAuth credentials.
- No credential found for user
- No credential found for user
- Failed to fetch Basecamp projects
- You must be logged in to do this
AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12).
Data as JSON: /api/errors/a9a3f9975be67de6.
Report an issue: GitHub.