{"record":{"id":"495369e5fcd06938","repo":"transloadit/uppy","slug":"failed-to-create-a-session","errorCode":null,"errorMessage":"Failed to create a session","messagePattern":"Failed to create a session","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@uppy/core/src/companion-client/googlePicker.ts","lineNumber":394,"sourceCode":"  // https://developers.google.com/photos/picker/guides/get-started-picker\n  const headers = getAuthHeader(token)\n\n  let newPickingSession = pickingSession\n  if (newPickingSession == null) {\n    const createSessionResponse = await fetch(\n      'https://photospicker.googleapis.com/v1/sessions',\n      { method: 'post', headers, signal },\n    )\n\n    if (createSessionResponse.status === 401) {\n      const resp = await createSessionResponse.json()\n      if (resp.error?.status === 'UNAUTHENTICATED') {\n        throw new InvalidTokenError()\n      }\n    }\n\n    if (!createSessionResponse.ok) {\n      throw new Error('Failed to create a session')\n    }\n    newPickingSession = (await createSessionResponse.json()) as PickingSession\n\n    onPickingSessionChange(newPickingSession)\n  }\n\n  const w = window.open(newPickingSession.pickerUri)\n  signal?.addEventListener('abort', () => w?.close())\n}\n\nasync function resolvePickedPhotos({\n  accessToken,\n  pickingSession,\n  signal,\n}: {\n  accessToken: string\n  pickingSession: PickingSession\n  signal: AbortSignal","sourceCodeStart":376,"sourceCodeEnd":412,"githubUrl":"https://github.com/transloadit/uppy/blob/5d4dedd02a1ac0ae022c75c54aca76558f88e256/packages/@uppy/core/src/companion-client/googlePicker.ts#L376-L412","documentation":"Thrown when creating a Photos picking session fails: the POST to https://photospicker.googleapis.com/v1/sessions returned a non-OK status (after the UNAUTHENTICATED case was already handled as InvalidTokenError). It aborts showPhotosPicker before any UI polling starts, meaning the Google Photos Picker backend rejected session creation.","triggerScenarios":"Calling the photos picker flow (showPhotosPicker) where the create-session request fails — invalid/expired token (non-UNAUTHENTICATED flavor), Photos Picker API not enabled, or a server-side 5xx.","commonSituations":"'Google Photos Picker API' not enabled in the Google Cloud project; missing photospicker scope; app verification pending for sensitive Google Photos scopes; transient Google-side errors.","solutions":["Enable the 'Google Photos Picker API' in Google Cloud Console for the client ID's project","Ensure the access token is requested with the https://www.googleapis.com/auth/photospicker scope","Verify app verification status for Photos scopes (restricted scopes require Google review)","Retry — transient 5xx from the Picker backend resolves on its own"],"exampleFix":"// before\nrenderButton(uppy, { clientId: 'xxx' })\n// -> Error: Failed to create a session (API not enabled)\n\n// after\n// Google Cloud Console -> APIs & Services -> enable 'Google Photos Picker API'\nrenderButton(uppy, { clientId: 'xxx' }) // works","handlingStrategy":"fallback","validationCode":"// Pre-flight: confirm the Photos Picker API is enabled for this client\nawait fetch('https://photospicker.googleapis.com/v1/sessions', {\n  method: 'POST', headers: { Authorization: `Bearer ${token}` },\n}) // if 403 SERVICE_DISABLED, fix config before wiring the picker","typeGuard":"null","tryCatchPattern":"try {\n  await picker.showPicker()\n} catch (err) {\n  if (err.message === 'Failed to create a session') {\n    uppy.info('Google Photos picking unavailable. Falling back to Drive picker.', 'warning', 5000)\n  }\n}","preventionTips":["Enable Google Photos Picker API in Cloud Console","Include photospicker scope in token requests","Complete Google verification for restricted Photos scopes"],"tags":["google-picker","google-photos","session","api-not-enabled"],"backgroundTag":"google-api-not-enabled","analyzedSha":"5d4dedd02a1ac0ae022c75c54aca76558f88e256","analyzedAt":"2026-08-28T12:18:41.267Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}