{"record":{"id":"cd65018003c0acea","repo":"antiwork/gumroad","slug":"something-went-wrong-cd6501","errorCode":null,"errorMessage":"Something went wrong.","messagePattern":"Something went wrong\\.","errorType":"exception","errorClass":"ResponseError","httpStatus":null,"severity":"error","filePath":"app/javascript/data/circle_integration.ts","lineNumber":26,"sourceCode":"\ntype FetchCommunitiesSuccessResponse = { success: true; communities: CircleCommunity[] };\n\ntype FetchCommunitiesErrorResponse = { success: false };\n\ntype FetchSpaceGroupsSuccessResponse = { success: true; space_groups: CircleSpaceGroup[] };\n\ntype FetchSpaceGroupsErrorResponse = { success: false };\n\nexport const fetchCommunities = async (apiKey: string) => {\n  const response = await request({\n    method: \"GET\",\n    url: Routes.communities_integrations_circle_index_path({ format: \"json\", api_key: apiKey }),\n    accept: \"json\",\n  });\n  const responseData = typia.assert<FetchCommunitiesSuccessResponse | FetchCommunitiesErrorResponse>(\n    await response.json(),\n  );\n  if (!responseData.success) throw new ResponseError();\n  return { communities: responseData.communities };\n};\n\nexport const fetchSpaceGroups = async (apiKey: string, communityId: number) => {\n  const response = await request({\n    method: \"GET\",\n    url: Routes.space_groups_integrations_circle_index_path({\n      format: \"json\",\n      api_key: apiKey,\n      community_id: communityId,\n    }),\n    accept: \"json\",\n  });\n  const responseData = typia.assert<FetchSpaceGroupsSuccessResponse | FetchSpaceGroupsErrorResponse>(\n    await response.json(),\n  );\n  if (!responseData.success) throw new ResponseError();\n  return { spaceGroups: responseData.space_groups };","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/antiwork/gumroad/blob/afeacbd394069a1cbf0c6c50ee8e900925050370/app/javascript/data/circle_integration.ts#L8-L44","documentation":"Gumroad's frontend data layer throws ResponseError (default message \"Something went wrong.\", defined in app/javascript/utils/request.ts:27) when an API call fails. This line in fetchCommunities fires when GET /integrations/circle/communities.json answers with a JSON body of { success: false }. The controller (app/controllers/integrations/circle_controller.rb:6-13) returns exactly that when the api_key param is blank or when the upstream CircleApi.get_communities call fails (invalid API key, Circle outage/timeout, or a non-array response), so this error means the Circle connection itself is broken, not the HTTP transport.","triggerScenarios":"Calling fetchCommunities(apiKey) with an empty string api_key (controller line 7 short-circuits to success:false); a revoked or mistyped Circle API key (Circle answers 401 upstream and the controller collapses it to success:false with HTTP 200); a Circle API outage or timeout on their side; a changed upstream Circle response shape that is no longer an array.","commonSituations":"Seller pastes an expired or typo'd Circle API key into the integration form; the key was rotated in Circle but not updated in Gumroad; Circle has a partial outage while the seller opens the community picker; the integration was disconnected and stale form state submits an empty key.","solutions":["Re-enter the Circle API key: copy it fresh from Circle's developer/API settings into the Gumroad Circle integration field and let fetchCommunities re-run.","Verify the key against Circle directly: curl -H \"Authorization: Bearer <KEY>\" https://app.circle.so/api/v1/communities — a 401 there reproduces exactly what the controller swallows into success:false.","If the key is valid, check Circle's status page for an outage and retry once Circle recovers.","If you maintain this code, throw a specific message instead of the default so the picker can tell the seller the key is the problem (see exampleFix)."],"exampleFix":"// before (circle_integration.ts:26)\nif (!responseData.success) throw new ResponseError();\n\n// after\nif (!responseData.success)\n  throw new ResponseError(\"Couldn't load Circle communities. Check that the API key is valid and try again.\");","handlingStrategy":"try-catch","validationCode":"const apiKeyOk = typeof apiKey === \"string\" && apiKey.trim().length > 0;\nif (!apiKeyOk) throw new Error(\"Enter a Circle API key before loading communities.\");\nawait fetchCommunities(apiKey);","typeGuard":"import { ResponseError } from \"$app/utils/request\";\nconst isResponseError = (e: unknown): e is ResponseError => e instanceof ResponseError;","tryCatchPattern":"import { assertResponseError } from \"$app/utils/request\";\ntry {\n  const { communities } = await fetchCommunities(apiKey);\n} catch (e) {\n  assertResponseError(e); // rethrows genuine bugs\n  showAlert(\"Couldn't reach Circle. Check the API key and try again.\", \"error\");\n}","preventionTips":["Never call fetchCommunities with an empty key — the server short-circuits to success:false.","Take the api_key verbatim from the integration settings field; do not trim/transform it in transit.","After any Circle-side key rotation, update the Gumroad integration before opening the community picker.","Distinguish this from typia.assert failures: a TypeGuardError means the server answered non-JSON (auth page), while this ResponseError means success:false."],"tags":["circle","integration","api-key","third-party-api","fetch","typescript"],"backgroundTag":"third-party-api-key-invalid","analyzedSha":"afeacbd394069a1cbf0c6c50ee8e900925050370","analyzedAt":"2026-08-21T17:58:52.159Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}