{"record":{"id":"55d306cf432d98d7","repo":"mastra-ai/mastra","slug":"linear-api-returned-no-data","errorCode":null,"errorMessage":"Linear API returned no data.","messagePattern":"Linear API returned no data\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mastracode/factory/src/integrations/linear/integration.ts","lineNumber":265,"sourceCode":"    // Linear returns GraphQL errors (validation, missing scopes, …) with a\n    // 400 status — surface the actual message instead of just the code.\n    let detail: string | null = null;\n    try {\n      const errBody = (await res.json()) as { errors?: Array<{ message?: string }> };\n      detail = errBody.errors?.[0]?.message ?? null;\n    } catch {\n      // Non-JSON error body; fall back to the status code alone.\n    }\n    const err = new Error(`Linear API request failed (${res.status})${detail ? `: ${detail}` : ''}`);\n    (err as { status?: number }).status = res.status;\n    throw err;\n  }\n  const body = (await res.json()) as { data?: T; errors?: Array<{ message?: string }> };\n  if (body.errors?.length) {\n    throw new Error(`Linear API error: ${body.errors[0]?.message ?? 'unknown error'}`);\n  }\n  if (!body.data) {\n    throw new Error('Linear API returned no data.');\n  }\n  return body.data;\n}\n\nexport class LinearIntegration implements FactoryIntegration {\n  /** Stable integration identifier (see `../base.ts`). */\n  readonly id = 'linear';\n  /** Bound once by the factory via `initialize()` before any surface is used. */\n  #storage: LinearStorageHandle | undefined;\n  #projects: FactoryProjectsStorage | undefined;\n  #auth: RouteAuth | undefined;\n\n  /** Bind Linear's slice of the generic integration storage, the projects domain, and the host auth seam. */\n  initialize({\n    storage,\n    projects,\n    auth,\n  }: {","sourceCodeStart":247,"sourceCodeEnd":283,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/factory/src/integrations/linear/integration.ts#L247-L283","documentation":"After a 200 response with no GraphQL `errors`, `linearGraphql` still requires a `data` key; if `body.data` is absent or falsy it throws this message. Linear's GraphQL contract is that a 200 response without errors carries a `data` object, so its absence means an unexpected or malformed response from Linear.","triggerScenarios":"Linear (or an intermediary proxy/gateway) returns a 200 JSON body lacking `data` — e.g. an empty object `{}`, a proxy's HTML-to-JSON fallback, or an API change where a query returns null data without an errors array. Any `linearGraphql`-based call (fetchWorkspace, listProjects, listActiveIssues, comment mutations) can hit it.","commonSituations":"Corporate proxies or local mocks returning `{}` with 200; intercepting Linear traffic in tests with incomplete fixtures; transient Linear incidents returning empty bodies; querying a field whose value is null at the top level after a deprecation.","solutions":["Retry the request once — transient empty bodies usually resolve on the next call.","Log the raw response body around `linearGraphql` to see what actually came back.","If behind a proxy, check whether the proxy or a security product is rewriting the response.","If mocking Linear in tests, make fixtures mirror Linear's shape: `{ data: { ... } }`.","Check Linear's status page / changelog for API behavior changes if it persists."],"exampleFix":"// test fixture before (no data key)\nmockResponse = { status: 200, body: {} };\n// after\nmockResponse = { status: 200, body: { data: { organization: { name: 'Acme', urlKey: 'acme' } } } };","handlingStrategy":"retry","validationCode":"const res = await fetch(LINEAR_GRAPHQL_URL, { ...opts });\nconst text = await res.text();\nconst body = JSON.parse(text);\nif (res.ok && !body.errors && !body.data) {\n  throw new Error('Malformed Linear response: 200 without data — likely a proxy/mocks issue');\n}","typeGuard":"function hasData<T>(body: unknown): body is { data: T } {\n  return typeof body === 'object' && body !== null && 'data' in body && (body as { data?: unknown }).data != null;\n}","tryCatchPattern":"try {\n  return await integration.someGraphqlCall();\n} catch (err) {\n  if (err instanceof Error && err.message === 'Linear API returned no data.') {\n    await sleep(500);\n    return await integration.someGraphqlCall(); // retry once\n  }\n  throw err;\n}","preventionTips":["Make test fixtures mirror Linear's `{ data: ... }` envelope.","Audit proxies/gateways in front of api.linear.app for body rewrites.","Retry once on this error before surfacing to users.","Monitor Linear's status page during incidents."],"tags":["network","graphql","linear-api","unexpected-response"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}