janhq/jan · error · Error
Reasoning components must be used within Reasoning
Error message
Reasoning components must be used within Reasoning
What it means
useReasoning is a React context hook that reads ReasoningContext, populated only by the Reasoning provider component. When called outside a <Reasoning> ancestor the context is null and the hook throws this Error to surface the misuse immediately.
Solutions
- Wrap the consuming components in <Reasoning> ... </Reasoning>
- Ensure ReasoningTrigger and ReasoningContent are children of Reasoning, not siblings
- Guard with a non-throwing context hook if usage outside is legitimate
- Verify conditional rendering never mounts the consumer without the provider
Example fix
// before
<ReasoningTrigger />
<ReasoningContent /> // thrown: no context
// after
<Reasoning isStreaming={isStreaming} duration={duration}>
<ReasoningTrigger />
<ReasoningContent />
</Reasoning> Defensive patterns
Strategy: type-guard
Type guard
function useReasoningSafe() {
return useContext(ReasoningContext); // null outside provider
}
// consumer:
const ctx = useReasoningSafe();
if (ctx === null) throw new Error('Reasoning components must be used within Reasoning'); Try / catch
try {
render(<ReasoningContent />);
} catch (e) {
if (e.message.includes('must be used within Reasoning')) {
console.error('JSX error: wrap the component in <Reasoning>');
}
} Prevention
- Render ReasoningTrigger/ReasoningContent only inside <Reasoning>
- Add a unit test that mounts consumers without a provider and asserts the error
- When moving components, verify provider ancestry in the new location
- Use a nullable-context helper hook where outside usage is expected
When it happens
Trigger: Calling useReasoning (or rendering ReasoningTrigger/ReasoningContent outside the wrapper) without a <Reasoning> ancestor in the component tree.
Common situations: Moving the reasoning toggle or content block into a different parent during refactor; rendering reasoning parts in a message list without the Reasoning wrapper; isolated test/storybook mounting.
Related errors
- ChainOfThought components must be used within ChainOfThought
- DropDrawer components cannot be rendered outside the…
- Tool components must be used within Tool
- useSidebar must be used within a SidebarProvider.
- Backend installed but failed to refresh UI
AI-assisted analysis of janhq/jan@7205d770c1 (2026-09-17).
Data as JSON: /api/errors/d8561337db610cab.
Report an issue: GitHub.
Appendix: source
Thrown at web-app/src/components/ai-elements/reasoning.tsx:34
useMemo,
useState,
} from 'react'
import { Streamdown } from 'streamdown'
import { Shimmer } from './shimmer'
type ReasoningContextValue = {
isStreaming: boolean
isOpen: boolean
setIsOpen: (open: boolean) => void
duration: number | undefined
}
const ReasoningContext = createContext<ReasoningContextValue | null>(null)
export const useReasoning = () => {
const context = useContext(ReasoningContext)
if (!context) {
throw new Error('Reasoning components must be used within Reasoning')
}
return context
}
export type ReasoningProps = ComponentProps<typeof Collapsible> & {
isStreaming?: boolean
open?: boolean
defaultOpen?: boolean
onOpenChange?: (open: boolean) => void
duration?: number
}
const MS_IN_S = 1000
export const Reasoning = memo(
({
className,
isStreaming = false,View on GitHub (pinned to 7205d770c1)