{"record":{"id":"e89822052664961f","repo":"flipped-aurora/gin-vue-admin","slug":"server-and-web-plugin-names-must-match","errorCode":null,"errorMessage":"server and web plugin names must match","messagePattern":"server and web plugin names must match","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/service/system/auto_code_plugin.go","lineNumber":210,"sourceCode":"\t}\n\tif _, err = io.Copy(out, src); err != nil {\n\t\tout.Close()\n\t\treturn -1, -1, err\n\t}\n\tif err = out.Close(); err != nil {\n\t\treturn -1, -1, err\n\t}\n\n\tpaths, err := utils.Unzip(archivePath, tempDir)\n\tif err != nil {\n\t\treturn -1, -1, err\n\t}\n\tarchive, err := findPluginArchive(tempDir, filterFile(paths))\n\tif err != nil {\n\t\treturn -1, -1, err\n\t}\n\tif archive.server != nil && archive.web != nil && archive.server.name != archive.web.name {\n\t\treturn -1, -1, errors.New(\"server and web plugin names must match\")\n\t}\n\n\tvar serverTarget, webTarget string\n\tif archive.server != nil {\n\t\tserverTarget, err = pluginInstallRoot(global.GVA_CONFIG.AutoCode.Server, parentPlugin)\n\t\tif err != nil {\n\t\t\treturn -1, -1, err\n\t\t}\n\t\tif err = ensurePluginTargetAvailable(serverTarget, archive.server.name); err != nil {\n\t\t\treturn -1, -1, err\n\t\t}\n\t}\n\tif archive.web != nil {\n\t\twebTarget, err = pluginInstallRoot(global.GVA_CONFIG.AutoCode.Web, parentPlugin)\n\t\tif err != nil {\n\t\t\treturn -1, -1, err\n\t\t}\n\t\tif err = ensurePluginTargetAvailable(webTarget, archive.web.name); err != nil {","sourceCodeStart":192,"sourceCodeEnd":228,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/service/system/auto_code_plugin.go#L192-L228","documentation":"When installing a sub-plugin from an uploaded archive, the installer locates both a server-side and a web-side plugin package inside it. This error is thrown when both parts exist but their extracted plugin names differ. The installer refuses to proceed because server and web halves of a plugin must be installed under the same directory name.","triggerScenarios":"Calling the plugin Install API with a zip archive whose `server/` directory contains plugin `foo` (e.g. server/plugin/foo) while `web/` contains plugin `bar` (e.g. web/src/plugin/bar). Any mismatch between the directory name immediately under the server root and the one under the web root in the archive triggers it.","commonSituations":"Hand-assembled plugin zips where the web folder was renamed or copied from a differently-named plugin; packaging a new version of the server side but keeping an old web side with a renamed plugin; typo in one of the two directory names; building the archive manually instead of using the plugin packaging tool.","solutions":["Extract the archive and rename the web plugin directory (and any references to it) so it exactly matches the server plugin directory name.","Alternatively rename the server plugin directory to match the web one, whichever name is correct.","Repackage the archive with matching top-level `server/plugin/<name>` and `web/src/plugin/<name>` paths and retry the install.","If only one side is intended to ship, remove the other side from the archive so only one part is present."],"exampleFix":"// before (archive layout)\nserver/plugin/payment-gateway/\nweb/src/plugin/pay-gateway/\n// after\nserver/plugin/payment-gateway/\nweb/src/plugin/payment-gateway/","handlingStrategy":"validation","validationCode":"import { readZipEntries } from './zip'\nconst entries = await readZipEntries(file)\nconst serverName = entries.find(e => /(^|\\/)server\\/[^/]+\\//.test(e))?.split('/')[1]\nconst webName = entries.find(e => /(^|\\/)web\\/src\\/plugin\\/[^/]+\\//.test(e))?.split('/').pop()\nif (serverName && webName && serverName !== webName) {\n  throw new Error(`plugin name mismatch: server=${serverName} web=${webName}`)\n}","typeGuard":null,"tryCatchPattern":"try {\n  await installPlugin(archive)\n} catch (e) {\n  if (e.message.includes('names must match')) {\n    showHint('Archive contains differently-named server and web plugins; rename one side and repackage.')\n  } else { throw e }\n}","preventionTips":["Always package plugins with the official packaging tool instead of zipping folders by hand.","Keep the server and web plugin directory names identical in source control so packaging cannot diverge.","Open the zip and verify `server/plugin/<name>` and `web/src/plugin/<name>` match before upload."],"tags":["plugin-install","archive-validation","naming"],"backgroundTag":"plugin-archive-name-mismatch","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}