{"record":{"id":"c2a9c1666f7b8468","repo":"YMFE/yapi","slug":"plugin-route-path-conflict-please-try-rename-the","errorCode":null,"errorMessage":"Plugin Route path conflict, please try rename the path","messagePattern":"Plugin Route path conflict, please try rename the path","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/router.js","lineNumber":595,"sourceCode":"      action: 'importData',\n      path: 'import_data',\n      method: 'post'\n    }\n  ]\n};\n\nlet pluginsRouterPath = [];\n\nfunction addPluginRouter(config) {\n  if (!config.path || !config.controller || !config.action) {\n    throw new Error('Plugin Route config Error');\n  }\n  let method = config.method || 'GET';\n  // let routerPath = '/plugin/' + config.path;\n  // 支持 /api/open/plugin 前缀的 openApi\n  let routerPath = (config.prefix || '') + '/plugin/' + config.path;\n  if (pluginsRouterPath.indexOf(routerPath) > -1) {\n    throw new Error('Plugin Route path conflict, please try rename the path');\n  }\n  pluginsRouterPath.push(routerPath);\n  createAction(router, '/api', config.controller, config.action, routerPath, method, false);\n}\n\nyapi.emitHookSync('add_router', addPluginRouter);\n\nfor (let ctrl in routerConfig) {\n  let actions = routerConfig[ctrl];\n  actions.forEach(item => {\n    let routerController = INTERFACE_CONFIG[ctrl].controller;\n    let routerPath = INTERFACE_CONFIG[ctrl].prefix + item.path;\n    createAction(router, '/api', routerController, item.action, routerPath, item.method);\n  });\n}\n\nmodule.exports = router;\n","sourceCodeStart":577,"sourceCodeEnd":613,"githubUrl":"https://github.com/YMFE/yapi/blob/59bade3a8a43e7db077d38a4b0c7c584f30ddf8c/server/router.js#L577-L613","documentation":"addPluginRouter keeps a registry (pluginsRouterPath) of already-registered '/plugin/<path>' routes; registering the same computed routerPath twice throws this conflict error. Prevents two plugin routes from shadowing each other.","triggerScenarios":"Two plugins (or one plugin twice) define routes resolving to the same (prefix + '/plugin/' + path) string, e.g. both register path 'report' without distinct prefixes.","commonSituations":"Same plugin listed twice in config.json, two third-party plugins choosing identical route paths, plugin registered for both normal and open API prefixes incorrectly duplicating paths.","solutions":["Rename one plugin's route path so routerPaths are unique.","Remove duplicate plugin entries in config.json.","Use a distinct config.prefix for one of the conflicting routes (e.g. '/api/open')."],"exampleFix":"// before\naddPluginRouter({ path: 'report', controller: 'a', action: 'get' });\naddPluginRouter({ path: 'report', controller: 'b', action: 'get' }); // conflict\n// after\naddPluginRouter({ path: 'report', controller: 'a', action: 'get' });\naddPluginRouter({ path: 'report-v2', controller: 'b', action: 'get' });","handlingStrategy":"validation","validationCode":"const seen = new Set();\nfunction routeKey(cfg) { return (cfg.prefix || '') + '/plugin/' + cfg.path; }\n// before emitting:\nconst key = routeKey(cfg);\nif (seen.has(key)) throw new Error(`Duplicate plugin route: ${key}`);\nseen.add(key);","typeGuard":null,"tryCatchPattern":"try {\n  yapi.emitHookSync('add_router', addPluginRouter);\n} catch (e) {\n  if (e.message.includes('path conflict')) {\n    console.error('Two plugins registered the same /plugin/<path>; rename one');\n  } else { throw e; }\n}","preventionTips":["Namespace plugin route paths with the plugin name (path: 'myplugin/report').","Ensure each plugin appears only once in config.json.","Keep a registry of used plugin route paths when managing many plugins."],"tags":["plugin","routing","route-conflict"],"backgroundTag":"route-path-conflict","analyzedSha":"59bade3a8a43e7db077d38a4b0c7c584f30ddf8c","analyzedAt":"2026-08-29T08:45:22.203Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}