{"record":{"id":"7b670b5ab2df99c6","repo":"BabylonJS/Babylon.js","slug":"usecurveeditor-must-be-used-within-a-curveeditorpr","errorCode":null,"errorMessage":"useCurveEditor must be used within a CurveEditorProvider","messagePattern":"useCurveEditor must be used within a CurveEditorProvider","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/dev/inspector-v2/src/components/curveEditor/curveEditorContext.tsx","lineNumber":623,"sourceCode":"        () => ({\r\n            state,\r\n            actions,\r\n            observables: observables.current,\r\n        }),\r\n        [state, actions]\r\n    );\r\n\r\n    return <CurveEditorContext.Provider value={contextValue}>{children}</CurveEditorContext.Provider>;\r\n};\r\n\r\n/**\r\n * Hook to access the curve editor context\r\n * @returns The curve editor context value\r\n */\r\nexport function useCurveEditor(): CurveEditorContextValue {\r\n    const context = useContext(CurveEditorContext);\r\n    if (!context) {\r\n        throw new Error(\"useCurveEditor must be used within a CurveEditorProvider\");\r\n    }\r\n    return context;\r\n}\r\n","sourceCodeStart":605,"sourceCodeEnd":627,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/inspector-v2/src/components/curveEditor/curveEditorContext.tsx#L605-L627","documentation":"useCurveEditor is a React hook that reads the curve editor's React context, which only exists when a <CurveEditorProvider> ancestor is present. The library throws this error when the hook is called outside any provider, because the context value is null and there is no meaningful state to return. It is a fail-fast guard so developers get a clear message instead of a confusing null dereference later.","triggerScenarios":"Calling useCurveEditor() in a component rendered outside the CurveEditorProvider tree, e.g. a panel/extension mounted before or beside the CurveEditor, or a component moved above the provider after refactoring.","commonSituations":"Adding a custom inspector panel that consumes curve editor state without wrapping the app in CurveEditorProvider; rendering the consumer in a React portal that escapes the provider subtree; conditional rendering where the provider unmounts but consumers stay mounted; mixing two inspector instances so the hook reads the wrong tree.","solutions":["Wrap the consuming component tree with <CurveEditorProvider> above the component calling useCurveEditor.","Move the consuming component so it renders as a descendant of the existing CurveEditorProvider.","If the component may render outside the provider, use a nullable read of useContext(CurveEditorContext) and render a fallback instead of throwing.","Verify only one provider wraps the tree and that portals (ReactDOM.createPortal) are created inside the provider subtree."],"exampleFix":"// before\nexport const MyPanel = () => {\n  const { state } = useCurveEditor();\n  return <div>{state.selectedCurve}</div>;\n};\n\n// after\n<CurveEditorProvider>\n  <MyPanel />\n</CurveEditorProvider>","handlingStrategy":"validation","validationCode":"import { useContext } from \"react\";\nimport { CurveEditorContext } from \"./curveEditorContext\";\nconst ctx = useContext(CurveEditorContext);\nif (!ctx) {\n  // render fallback instead of calling useCurveEditor()\n}","typeGuard":"function hasCurveEditorContext(ctx: CurveEditorContextValue | null): ctx is CurveEditorContextValue {\n  return ctx !== null && ctx !== undefined;\n}","tryCatchPattern":"try {\n  const ctx = useCurveEditor();\n  // use ctx\n} catch (e) {\n  if (e instanceof Error && e.message.includes(\"CurveEditorProvider\")) {\n    return <CurveEditorUnavailableFallback />;\n  }\n  throw e;\n}","preventionTips":["Always mount consumers inside <CurveEditorProvider>.","Create portals from inside the provider subtree.","Add a lint/test asserting the provider wraps the inspector tree.","Prefer a nullable context read plus fallback for optional features."],"tags":["react","context-provider","hooks"],"backgroundTag":"hook-used-outside-provider","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}