{"record":{"id":"aeca6e5741be6f8d","repo":"transloadit/uppy","slug":"not-implemented","errorCode":null,"errorMessage":"Not implemented","messagePattern":"Not implemented","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@uppy/aws-s3/src/s3-client/S3Client.ts","lineNumber":122,"sourceCode":"        if (xhr.status >= 400 && xhr.status < 500 && xhr.status !== 429) {\n          return false\n        }\n        return true\n      },\n      onUploadProgress: (event) => {\n        if (event.lengthComputable && onProgress) {\n          onProgress(event.loaded, event.total)\n        }\n      },\n    })\n  }\n\n  public async putObject(params: IT.PutObjectParams): Promise<{\n    location: string\n    key: string\n    etag: string | undefined\n  }> {\n    throw new Error('Not implemented')\n  }\n\n  public async createMultipartUpload(\n    params: IT.CreateMultipartUploadParams,\n  ): Promise<{\n    uploadId: string\n    key: string\n  }> {\n    throw new Error('Not implemented')\n  }\n\n  public async uploadPart(params: IT.UploadPartParams): Promise<{\n    etag: string\n  }> {\n    throw new Error('Not implemented')\n  }\n\n  public async listParts(params: IT.ListPartsParams): Promise<IT.UploadPart[]> {","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/transloadit/uppy/blob/5d4dedd02a1ac0ae022c75c54aca76558f88e256/packages/@uppy/aws-s3/src/s3-client/S3Client.ts#L104-L140","documentation":"The refresh-token endpoint requires the stored provider session to contain a refreshToken. Some providers issue short-lived access tokens without refresh tokens, and Companion logs 'Tried to refresh token without having a token' and returns 401 instead of attempting a refresh.","triggerScenarios":"Calling refresh-token when providerUserSession.refreshToken is undefined — e.g. the OAuth flow granted no offline access scope, or the session was created before refresh support, or the provider simply does not issue refresh tokens (Instagram-style flows).","commonSituations":"Google Drive without the access_type=offline / prompt=consent parameters in grant config; provider grant dynamic config missing; session data truncated so refreshToken was dropped; client automatically retrying refresh on expired access tokens for a provider that cannot refresh.","solutions":["For Google, add access_type: 'offline' and prompt: 'consent' to the provider's grant/dynamic config so a refresh token is issued","Re-authenticate the user to obtain a session that includes a refresh token","If the provider does not support refresh tokens, catch 401 and prompt re-authentication instead of retrying refresh"],"exampleFix":"// before\ncompanion({ providerOptions: { drive: { key, secret } } })\n// after\n// ensure Google issues a refresh token on consent\nnew GoogleDrive(uppy, { companionUrl, companionCookiesRule: 'same-origin' })\n// plus on server, grant config:\ncompanion({\n  providerOptions: { drive: { key, secret } },\n  // grant dynamic: access_type=offline&prompt=consent handled via provider config\n})","handlingStrategy":"fallback","validationCode":"// client-side: only attempt refresh when the session was granted offline access\nif (!sessionHasRefreshToken) return promptReauthentication()","typeGuard":"const canRefresh = (session: { refreshToken?: string }): session is { refreshToken: string } =>\n  typeof session.refreshToken === 'string' && session.refreshToken.length > 0","tryCatchPattern":"try {\n  await refreshAccessToken()\n} catch (e) {\n  if (e.status === 401) return promptReauthentication() // no refresh token available\n  throw e\n}","preventionTips":["Request offline access (e.g. Google access_type=offline, prompt=consent) when you need refresh support","Never retry 401 from refresh-token; it means re-auth is required","Store and inspect the full provider session including refreshToken"],"tags":["companion","refresh-token","http-401","oauth"],"backgroundTag":"oauth-refresh-token-missing","analyzedSha":"5d4dedd02a1ac0ae022c75c54aca76558f88e256","analyzedAt":"2026-08-28T12:18:41.267Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}