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

  1. Remove the duplicate bindHook call or guard it with a check before binding.
  2. Ensure the plugin is listed only once in config.json plugins array.
  3. 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

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


AI-assisted analysis of YMFE/yapi@59bade3a8a (2026-08-29). Data as JSON: /api/errors/3047bb37f42f1ed8. Report an issue: GitHub.