shadcn-ui/ui · error · Error

useProgress must be used within a Progress.

Error message

useProgress must be used within a Progress.

What it means

`useProgress` reads `ProgressContext` (`createContext<ProgressContextValue | null>(null)`); `<ProgressContent>` supplies `{ percentage, isIndeterminate, valueText }`. A consumer rendered outside `<ProgressContent>` (or `<Progress>` that composes it) throws so progress rendering never reads null.

Source

Thrown at apps/v4/registry/bases/aria/ui/progress.tsx:24

  ProgressBar as ProgressPrimitive,
  type LabelProps,
  type ProgressBarProps as ProgressPrimitiveProps,
} from "react-aria-components"

import { cn } from "@/registry/bases/aria/lib/utils"

type ProgressContextValue = {
  percentage?: number
  isIndeterminate: boolean
  valueText?: string
}

const ProgressContext = React.createContext<ProgressContextValue | null>(null)

function useProgress() {
  const context = React.useContext(ProgressContext)
  if (!context) {
    throw new Error("useProgress must be used within a Progress.")
  }

  return context
}

function ProgressContent({
  children,
  percentage,
  isIndeterminate,
  valueText,
}: ProgressContextValue & {
  children?: React.ReactNode
}) {
  const context = React.useMemo(
    () => ({ percentage, isIndeterminate, valueText }),
    [percentage, isIndeterminate, valueText]
  )

View on GitHub (pinned to efac598707)

Solutions

  1. Place any `useProgress()` consumer inside `<ProgressContent>` (or `<Progress>` that mounts it), passing `percentage`/`isIndeterminate`/`valueText` as needed.
  2. If you need a standalone indicator, pass props directly instead of via the hook.
  3. Decorate tests/stories with `<ProgressContent>`.

Example fix

// before
<ProgressIndicator />

// after
<Progress>
  <ProgressContent percentage={42} isIndeterminate={false}>
    <ProgressIndicator />
  </ProgressContent>
</Progress>
Defensive patterns

Strategy: type-guard

Validate before calling

render(<Progress><ProgressContent percentage={50} isIndeterminate={false}>{<Indicator/>}</ProgressContent></Progress>)

Type guard

import React from "react"
import { ProgressContext } from "@/registry/bases/aria/ui/progress"
const insideProgress = () => React.useContext(ProgressContext) != null

Try / catch

try { useProgress() } catch (e) { if (e.message.includes("Progress.")) {/*nest under ProgressContent*/} throw e }

Prevention

When it happens

Trigger: Mounting an aria-style progress sub-component (e.g. a custom indicator that calls `useProgress()`) outside `<ProgressContent>` / `<Progress>`. Happens when decomposing the progress composition for a bespoke layout.

Common situations: Building a custom progress layout; reusing the inner indicator in isolation; tests rendering the indicator alone.

Related errors


AI-assisted analysis of shadcn-ui/ui@efac598707 (2026-08-12). Data as JSON: /api/errors/2c1af0a534bdfae7. Report an issue: GitHub.