{"record":{"id":"94d5b92f5eccdbfe","repo":"supabase/supabase","slug":"failed-to-fetch-full-values-for-truncated-cells","errorCode":null,"errorMessage":"Failed to fetch full values for truncated cells","messagePattern":"Failed to fetch full values for truncated cells","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/studio/components/grid/components/header/Header.tsx","lineNumber":249,"sourceCode":"            A selected row has a column value that needs to be fetched on demand due to its size,\n            but the table has no primary key.\n          </p>\n        </div>,\n        { duration: 8000 }\n      )\n    }\n\n    setIsCopying(true)\n    const formatted = (async () => {\n      const hydrated = await hydrateTruncatedRows({\n        rows: selected,\n        table: snap.table,\n        projectRef: project.ref,\n        connectionString: project.connectionString ?? null,\n        roleImpersonationState: roleImpersonationState as RoleImpersonationState,\n      })\n      if (hydrated.status !== 'ok') {\n        throw new Error('Failed to fetch full values for truncated cells')\n      }\n      const rows = hydrated.rows\n      if (type === 'csv') {\n        return formatRowsForCSV({\n          rows,\n          columns: snap.table!.columns.map((column) => column.name),\n        })\n      } else if (type === 'sql') {\n        return formatTableRowsToSQL(snap.table, rows)\n      } else {\n        return JSON.stringify(rows)\n      }\n    })()\n\n    copyToClipboard(formatted, () => toast.success('Copied rows to clipboard')).finally(() => {\n      setIsCopying(false)\n    })\n  }","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/supabase/supabase/blob/beee91b9c2228dd57302dec75c733baaa84ab543/apps/studio/components/grid/components/header/Header.tsx#L231-L267","documentation":"Thrown in onCopyRows when hydrateTruncatedRows (a server query that fetches full values for cells whose displayed value was truncated) returns a non-'ok' status. This only fires for tables that have truncated string values AND a primary key (tables without a PK are blocked earlier with a dedicated toast). The error indicates the on-demand fetch of full cell values failed.","triggerScenarios":"User selects rows containing truncated (oversized) cell values and copies them as CSV/JSON/SQL; the hydrate query to fetch full values by primary key fails (DB error, timeout, connection issue, or role-impersonation conflict).","commonSituations":"Large text/jsonb columns whose display is truncated; network blip or DB load during the hydration query; role impersonation or RLS blocking the select; connectionString stale; project paused.","solutions":["Retry the copy — transient DB/network errors often resolve on the second attempt.","If using role impersonation, switch to a role with SELECT on the truncated columns and retry.","Verify the project is not paused and the database is reachable.","As a workaround, run a direct SELECT in the SQL editor for the specific primary keys to fetch full values manually."],"exampleFix":"// before\nconst hydrated = await hydrateTruncatedRows({ rows: selected, table: snap.table, projectRef, connectionString, roleImpersonationState })\nif (hydrated.status !== 'ok') {\n  throw new Error('Failed to fetch full values for truncated cells')\n}\n\n// after — surface the underlying failure reason\nif (hydrated.status !== 'ok') {\n  toast.error(`Failed to fetch full values for truncated cells: ${hydrated.error?.message ?? 'unknown error'}`)\n  return\n}","handlingStrategy":"try-catch","validationCode":"// Pre-check: only attempt hydration when there are truncated cells and a usable PK\nconst canHydrate = snap.table.primaryKey && snap.table.primaryKey.length > 0 && selected.some((r) => Object.values(r).some((v) => typeof v === 'string' && isValueTruncated(v)))\nif (!canHydrate) { /* skip hydration / warn user */ }","typeGuard":"function isHydrateOk(r: unknown): r is { status: 'ok'; rows: any[] } {\n  return typeof r === 'object' && r !== null && (r as any).status === 'ok'\n}","tryCatchPattern":"copyToClipboard((async () => {\n  const hydrated = await hydrateTruncatedRows({ ... })\n  if (hydrated.status !== 'ok') {\n    toast.error(`Failed to fetch full values: ${(hydrated as any).error?.message ?? 'unknown'}`)\n    return null\n  }\n  return formatRowsForCSV({ rows: hydrated.rows, columns: snap.table!.columns.map((c) => c.name) })\n})(), () => toast.success('Copied'))","preventionTips":["Ensure the table has a primary key before offering copy of truncated rows.","Retry transient hydration failures before giving up.","Surface the underlying hydrate error reason to the user instead of a generic message."],"tags":["grid","clipboard","database","network","client-side"],"backgroundTag":null,"analyzedSha":"beee91b9c2228dd57302dec75c733baaa84ab543","analyzedAt":"2026-08-12T06:51:48.935Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}