jeecgboot/JeecgBoot · error
useDescription() can only be used inside setup() or function
Error message
useDescription() can only be used inside setup() or functional components!
What it means
useDescription is a Vue 3 composition-API hook that pairs a Description component with its controller via a register/callback pattern. Like all such hooks, it requires an active component instance to register lifecycle hooks (onUnmounted). It guards by checking getCurrentInstance() at call time — if null, the hook is being invoked outside of setup() and lifecycle registration would silently fail, so it throws immediately rather than producing a broken ref.
Source
Thrown at jeecgboot-vue3/src/components/Description/src/useDescription.ts:7
import type { DescriptionProps, DescInstance, UseDescReturnType } from './typing';
import { ref, getCurrentInstance, unref, onUnmounted } from 'vue';
import { isProdMode } from '/@/utils/env';
export function useDescription(props?: Partial<DescriptionProps>): UseDescReturnType {
if (!getCurrentInstance()) {
throw new Error('useDescription() can only be used inside setup() or functional components!');
}
const desc = ref<Nullable<DescInstance>>(null);
const loaded = ref(false);
function register(instance: DescInstance) {
// update-begin--author:liaozhiyang---date:20251223---for:【pull/9125】在抽屉中配置destroy-on-close,再次打开未正确渲染
isProdMode() &&
onUnmounted(() => {
desc.value = null;
loaded.value = false;
});
if (unref(loaded) && isProdMode() && instance === unref(desc)) return;
// update-end--author:liaozhiyang---date:20251223---for:【pull/9125】在抽屉中配置destroy-on-close,再次打开未正确渲染
desc.value = instance;
props && instance.setDescProps(props);
loaded.value = true;
}
View on GitHub (pinned to 96fb33f5ec)
Solutions
- Move the useDescription() call to the top level of <script setup> or the setup() function body.
- If extracting into a composable, ensure the composable itself is called synchronously from setup and calls useDescription synchronously.
- Avoid wrapping the call in async/await at the top level — call it first, then await.
- If you genuinely need to trigger actions outside setup, use the returned methods object (openModal-style) rather than calling the hook again.
Example fix
// before — called in an async callback
onMounted(async () => {
const [register, desc] = useDescription(); // throws
});
// after — call synchronously at setup top level
const [register, desc] = useDescription();
onMounted(async () => { /* use desc */ }); Defensive patterns
Strategy: validation
Validate before calling
// Guard the hook call so misuse fails with a clear message in dev
import { getCurrentInstance } from 'vue';
function safeUseDescription(props?: Partial<DescriptionProps>) {
if (!getCurrentInstance()) {
console.warn('useDescription called outside setup — skipping');
return null;
}
return useDescription(props);
} Type guard
import { getCurrentInstance } from 'vue';
function isInSetup(): boolean {
return !!getCurrentInstance();
} Try / catch
// If you must call conditionally
let desc;
try {
desc = useDescription();
} catch (e) {
// handle missing setup context gracefully
} Prevention
- Always call composition hooks at the top of <script setup>, synchronously.
- Never place hook calls inside async callbacks or setTimeout.
- When extracting composables, ensure they run within setup and call hooks synchronously.
When it happens
Trigger: Calling useDescription() at module top-level, inside a plain function (not a Vue setup context), inside an async callback resolved after setup returns, inside a setTimeout/setInterval handler, or inside a Pinia store action. Also triggered by calling it inside <script setup> but in a top-level await continuation that detaches from the instance context.
Common situations: Refactoring that moves the hook call out of setup; extracting logic into a composable that forgets to forward the setup context; calling openDescription inside an event handler defined outside setup; SSR or testing utilities that mount components without a proper instance.
Related errors
- useDrawer() can only be used inside setup() or functional co
- useDrawerInner() can only be used inside setup() or function
- useModal() can only be used inside setup() or functional com
- useTableContext must be used after createTableContext
- 【addComponent】不能使用"${type}"作为组件的name,因为这是关键字。
AI-assisted analysis of jeecgboot/JeecgBoot@96fb33f5ec (2026-08-14).
Data as JSON: /api/errors/47dd4dc098de8cca.
Report an issue: GitHub.