{"record":{"id":"969ced68f871f2c2","repo":"calcom/cal.diy","slug":"invalid-refreshed-tokens-were-returned","errorCode":null,"errorMessage":"Invalid refreshed tokens were returned","messagePattern":"Invalid refreshed tokens were returned","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/app-store/_utils/oauth/parseRefreshTokenResponse.ts","lineNumber":36,"sourceCode":"  });\n\nexport type ParseRefreshTokenResponse<S extends z.ZodTypeAny> =\n  | z.infer<S>\n  | z.infer<typeof minimumTokenResponseSchema>;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst parseRefreshTokenResponse = (response: any, schema: z.ZodTypeAny) => {\n  let refreshTokenResponse;\n  const credentialSyncingEnabled =\n    APP_CREDENTIAL_SHARING_ENABLED && process.env.CALCOM_CREDENTIAL_SYNC_ENDPOINT;\n  if (APP_CREDENTIAL_SHARING_ENABLED && process.env.CALCOM_CREDENTIAL_SYNC_ENDPOINT) {\n    refreshTokenResponse = minimumTokenResponseSchema.safeParse(response);\n  } else {\n    refreshTokenResponse = schema.safeParse(response);\n  }\n\n  if (!refreshTokenResponse.success) {\n    throw new Error(\"Invalid refreshed tokens were returned\");\n  }\n\n  if (!refreshTokenResponse.data.refresh_token && credentialSyncingEnabled) {\n    refreshTokenResponse.data.refresh_token = \"refresh_token\";\n  }\n\n  return refreshTokenResponse.data;\n};\n\nexport default parseRefreshTokenResponse;\n","sourceCodeStart":18,"sourceCodeEnd":47,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/packages/app-store/_utils/oauth/parseRefreshTokenResponse.ts#L18-L47","documentation":"Thrown by parseRefreshTokenResponse when the refreshed token object fails its Zod schema validation. In credential-sync mode it validates against minimumTokenResponseSchema (requires access_token plus at least one numeric expiry-ish field); otherwise against the app-specific schema passed in. A failure means the provider (or sync server) returned a shape that does not match the expected token contract.","triggerScenarios":"The token-refresh response is missing access_token, missing any numeric expiry field (in sync mode), or does not match the app's specific token schema (e.g. missing expires_in/refresh_token that the app requires). Happens when the provider changes its token format, returns an error body shaped like a token, or the sync server returns a partial payload.","commonSituations":"See trigger scenarios.","solutions":["Log the raw response and the Zod issues (the caller already logs oauth2response/issues) to see which field failed.","If the provider changed its token shape, update the app's token schema accordingly.","Ensure the credential-sync server returns at least access_token and a numeric expiry field.","Confirm the refresh succeeded (a 401/invalid_grant error body parsed as a token will fail validation)."],"exampleFix":"// before - schema rejects provider response that uses 'expires_at' string\nconst schema = z.object({ access_token: z.string(), expires_in: z.number() });\n// after - accept the provider's actual shape\nconst schema = z.object({\n  access_token: z.string(),\n  expires_in: z.number().optional(),\n  expires_at: z.string().optional(),\n});","handlingStrategy":"try-catch","validationCode":"const refreshTokenResponse = schema.safeParse(response);\nif (!refreshTokenResponse.success) {\n  // log issues before throwing so the cause is diagnosable\n  console.error('Token schema failure', refreshTokenResponse.error.issues, response);\n}","typeGuard":"function isValidTokenResponse<T extends z.ZodTypeAny>(resp: unknown, schema: T): resp is z.infer<T> {\n  return schema.safeParse(resp).success;\n}","tryCatchPattern":"try {\n  return parseRefreshTokenResponse(response, schema);\n} catch (e) {\n  // re-fetch or invalidate the token object; surface a reconnect prompt to the user\n  throw new Error('OAuth token refresh returned an invalid shape; re-authorization may be required.');\n}","preventionTips":["Log the raw refresh response and Zod issues to pinpoint the missing field.","Keep the app's token schema aligned with the provider's actual response shape.","Ensure the credential-sync server returns access_token plus a numeric expiry field."],"tags":["oauth","tokens","zod","validation","refresh","credential-sync"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}