TanStack/table · error

`useCellContext` must be used within an `AppCell` component.

Error message

`useCellContext` must be used within an `AppCell` component. Make sure your component is wrapped with `<table.AppCell cell={cell}>...</table.AppCell>`.

What it means

`useCellContext` in the Solid adapter reads the cell context provided by `<table.AppCell cell={cell}>`. Without that provider above the caller, the context is undefined and this error is thrown, so cell APIs are only reachable with a real cell. AppCell also attaches `cellComponents` and `FlexRender` to the cell instance it provides.

Source

Thrown at packages/solid-table/src/createTableHook.tsx:714

   *   return <span>{cell.getValue()}</span>
   * }
   *
   * function NumberCell({ format }: { format?: Intl.NumberFormatOptions }) {
   *   const cell = useCellContext<number>()
   *   return <span>{cell.getValue().toLocaleString(undefined, format)}</span>
   * }
   * ```
   */
  function useCellContext<TValue extends CellData = CellData>(): Cell<
    TFeatures,
    any,
    TValue
  > &
    TCellComponents & { FlexRender: () => JSXElement } {
    const cell = useContext(CellContext)

    if (!cell) {
      throw new Error(
        '`useCellContext` must be used within an `AppCell` component. ' +
          'Make sure your component is wrapped with `<table.AppCell cell={cell}>...</table.AppCell>`.',
      )
    }

    // `<table.AppCell>` Object.assign-es `cellComponents` and `FlexRender` onto
    // the same cell instance it provides, so this asserts the runtime shape.
    return cell as unknown as Cell<TFeatures, any, TValue> &
      TCellComponents & { FlexRender: () => JSXElement }
  }

  /**
   * Access the header instance from within an `AppHeader` or `AppFooter` wrapper.
   * Use this in custom `headerComponents` passed to `createTableHook`.
   * TFeatures is already known from the createTableHook call.
   *
   * @example
   * ```tsx

View on GitHub (pinned to d01c01bedb)

Solutions

  1. Wrap the component with `<table.AppCell cell={cell}>...</table.AppCell>`.
  2. Move the component into AppCell's children in the column def's cell renderer.
  3. Dedupe solid-table so all consumers share one context module.
  4. Use `useContext(CellContext)` directly with a null check when the cell may be absent.

Example fix

// before
function CellBadge() {
  const cell = useCellContext()
  return <span>{String(cell.getValue())}</span>
}

// after
<table.AppCell cell={cell}>
  <CellBadge />
</table.AppCell>
Defensive patterns

Strategy: validation

Validate before calling

import { useContext } from 'solid-js'
import { CellContext } from '@your-scope/solid-table'

function useSafeCell() {
  const cell = useContext(CellContext)
  if (!cell) {
    console.error('useCellContext requires <table.AppCell cell={cell}> above this component')
  }
  return cell
}

Type guard

function hasCell<T>(c: T | null | undefined): c is T {
  return c != null
}

Try / catch

try {
  const cell = useCellContext()
  // use cell
} catch (err) {
  if (err instanceof Error && err.message.includes('useCellContext')) {
    return null
  }
  throw err
}

Prevention

When it happens

Trigger: Calling `useCellContext()` in a component outside `<table.AppCell cell={cell}>`; rendering via solid Portal outside the provider; duplicate solid-table installs breaking context identity.

Common situations: Custom Solid cell renderers extracted into shared components without a provider; isolated test mounts; version duplication in monorepos.

Related errors


AI-assisted analysis of TanStack/table@d01c01bedb (2026-08-28). Data as JSON: /api/errors/e83007a4c73dbf60. Report an issue: GitHub.