youzan/vant-weapp · warning
未找到 van-toast 节点,请确认 selector 及 context 是否正确
Error message
未找到 van-toast 节点,请确认 selector 及 context 是否正确
What it means
This warning is emitted by Vant Weapp's Toast() (also via the createMethod shortcuts Toast.loading/Toast.success/Toast.fail, which call the same function) when context.selectComponent(options.selector) cannot find a <van-toast> component instance. The imperative Toast API only configures and shows an existing <van-toast id="van-toast"> node declared in WXML; if it can't be resolved, the library warns and returns undefined instead of showing the toast, and any returned-instance chaining fails.
Source
Thrown at packages/toast/toast.ts:61
function getContext() {
const pages = getCurrentPages();
return pages[pages.length - 1];
}
function Toast(toastOptions: ToastOptions | ToastMessage) {
const options = {
...currentOptions,
...parseOptions(toastOptions),
} as ToastOptions;
const context =
(typeof options.context === 'function'
? options.context()
: options.context) || getContext();
const toast = context.selectComponent(options.selector as string);
if (!toast) {
console.warn('未找到 van-toast 节点,请确认 selector 及 context 是否正确');
return;
}
delete options.context;
delete options.selector;
toast.clear = () => {
toast.setData({ show: false });
if (options.onClose) {
options.onClose();
}
};
queue.push(toast);
toast.setData(options);
clearTimeout(toast.timer);
View on GitHub (pinned to 7a7d43757e)
Solutions
- Add <van-toast id="van-toast" /> to the WXML of every page (or the containing component) that uses the imperative Toast API, and register the component in the page JSON.
- If the node is in a child component, pass options.context: () => this.selectComponent('#child') (or the instance) so selectComponent searches the right subtree.
- If you renamed the node, pass the matching selector, e.g. Toast.success({ selector: '#my-toast', message: 'ok' }).
- Call Toast only from page/component code after the page has rendered (e.g. onReady or later event handlers), not from App.onLaunch.
- Guard on the return value: Toast returns the instance on success and undefined here — check it before calling instance-based APIs like toast.clear().
Example fix
// before
Toast.loading({ message: 'Loading...', context: this.selectComponent('#child') }); // node lives in child but selectComponent called on child's own scope may miss/wrong scope
// after
Toast.loading({ message: 'Loading...', context: () => this.selectComponent('#child') });
// and page.wxml (or child wxml) contains:
// <van-toast id="van-toast" /> Defensive patterns
Strategy: validation
Validate before calling
function assertToastNode(context?: (() => object) | object, selector = '#van-toast') {
const ctx =
(typeof context === 'function' ? context() : context) ||
getCurrentPages()[getCurrentPages().length - 1];
if (!ctx || typeof ctx.selectComponent !== 'function' || !ctx.selectComponent(selector)) {
throw new Error(
`<van-toast ${selector}> not found. Add <van-toast id="van-toast" /> to the page WXML and register it in usingComponents.`
);
}
}
// call before Toast()/Toast.loading etc:
// assertToastNode(() => this.selectComponent('#child')); Type guard
function isToastInstance(v: unknown): v is { clear(): void; setData(d: object): void; timer?: number } {
return !!v && typeof (v as any).clear === 'function';
} Try / catch
try {
const toast = Toast.loading({ message: 'Loading...', context: () => this.selectComponent('#child') });
if (!isToastInstance(toast)) {
throw new Error('van-toast node not found; check selector/context');
}
} catch (e) {
console.warn('Toast failed:', e);
wx.showLoading({ title: 'Loading' }); // native fallback
} Prevention
- Add <van-toast id="van-toast" /> to every page WXML that uses the imperative Toast API (Toast, Toast.loading/success/fail); maintain a page template that includes it.
- If the node lives in a child component, always pass context: () => this.selectComponent('#child') so selectComponent searches the correct subtree.
- Match custom ids to options.selector exactly, including the leading '#'.
- Only call Toast after a page exists and has rendered (event handlers, onReady+), never in App.onLaunch.
- Check the return value before using instance methods like toast.clear(); undefined means the node was missing.
When it happens
Trigger: Calling Toast('msg') or Toast.loading/success/fail when (1) the page WXML lacks <van-toast id="van-toast" />, (2) options.selector is set to a custom id that doesn't exist in the resolved context, (3) options.context (instance or () => instance) resolves to a page/component that doesn't directly contain the <van-toast> node, or (4) the call happens while getCurrentPages() is empty or before the page tree is available, so the fallback getContext() yields nothing useful.
Common situations: Calling Toast from a shared utility/service module while the toast node was added to only some pages; forgetting to add <van-toast id="van-toast" /> to a newly created page that imports the imperative API; declaring the node inside a custom component and calling Toast.success from the page without passing context: () => this.selectComponent('#child'); giving the node a different id (e.g. id="toast") while keeping the default selector '#van-toast'; calling Toast during onLaunch/App-level code before any page exists.
Related errors
AI-assisted analysis of youzan/vant-weapp@7a7d43757e (2026-09-02).
Data as JSON: /api/errors/51e1a1e758bac5ee.
Report an issue: GitHub.