YMFE/yapi · error
重复绑定singleHook(${name}), 请检查
Error message
重复绑定singleHook(${name}), 请检查 What it means
For 'single' type hooks only one listener is allowed; binding a second listener to the same single hook throws this error. Multi hooks accept an array of listeners, single hooks hold exactly one function.
Source
Thrown at server/plugin.js:203
* hander: (emails, title, content)=> {...}
* }
*/
addNotice:{
type: 'multi',
listener: []
}
};
function bindHook(name, listener) {
if (!name) throw new Error('缺少hookname');
if (name in hooks === false) {
throw new Error('不存在的hookname');
}
if (hooks[name].type === 'multi') {
hooks[name].listener.push(listener);
} else {
if (typeof hooks[name].listener === 'function') {
throw new Error('重复绑定singleHook(' + name + '), 请检查');
}
hooks[name].listener = listener;
}
}
/**
*
* @param {*} hookname
* @return promise
*/
function emitHook(name) {
if (hooks[name] && typeof hooks[name] === 'object') {
let args = Array.prototype.slice.call(arguments, 1);
if (hooks[name].type === 'single' && typeof hooks[name].listener === 'function') {
return Promise.resolve(hooks[name].listener.apply(yapi, args));
}
let promiseAll = [];
if (Array.isArray(hooks[name].listener)) {View on GitHub (pinned to 59bade3a8a)
Solutions
- Remove the duplicate bindHook call or guard it with a check before binding.
- Ensure the plugin is listed only once in config.json plugins array.
- If both bindings are needed, check whether the hook is defined as 'multi' type, or merge logic into one listener.
Example fix
// before
yapi.bindHook('init', initA);
yapi.bindHook('init', initB); // throws
// after
yapi.bindHook('init', () => { initA(); initB(); }); Defensive patterns
Strategy: try-catch
Try / catch
try {
yapi.bindHook('init', listener);
} catch (e) {
if (e.message.startsWith('重复绑定singleHook')) {
console.warn('Hook already bound, skipping duplicate bind');
} else { throw e; }
} Prevention
- Track bound hooks in your plugin with a Set and skip re-binding.
- List each plugin only once in config.json.
- Merge multiple init actions into a single listener for single hooks.
When it happens
Trigger: bindHook called twice with the same single-hook name, e.g. two plugins (or the same plugin loaded twice) both bindHook('init', fn).
Common situations: Duplicate plugin entries in config.json, plugin module accidentally required/loaded twice, two plugins targeting the same single hook point.
Related errors
- 缺少hookname
- 不存在的hookname
- config.json配置了插件${plugin},但plugins目录没有找到此插件,请安装此插件
- Plugin Route config Error
- Plugin Route path conflict, please try rename the path
AI-assisted analysis of YMFE/yapi@59bade3a8a (2026-08-29).
Data as JSON: /api/errors/3047bb37f42f1ed8.
Report an issue: GitHub.