{"record":{"id":"5463674c0fd4d00f","repo":"flipped-aurora/gin-vue-admin","slug":"error-546367","errorCode":null,"errorMessage":"非标准插件，请按照文档自动迁移使用","messagePattern":"非标准插件，请按照文档自动迁移使用","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/service/system/auto_code_plugin.go","lineNumber":116,"sourceCode":"\t\t}\n\t\tif pathArr[2]+\"/\"+pathArr[3] == `server/plugin` {\n\t\t\tif len(serverPlugin) == 0 {\n\t\t\t\tserverPlugin = filepath.Join(pathArr[0], pathArr[1], pathArr[2], pathArr[3])\n\t\t\t}\n\t\t\tif serverRootName == \"\" && ln > 1 && pathArr[1] != \"\" {\n\t\t\t\tserverRootName = pathArr[1]\n\t\t\t}\n\t\t\tif ln > 4 && serverPackage == \"\" && pathArr[4] != \"\" {\n\t\t\t\tserverPackage = pathArr[4]\n\t\t\t}\n\t\t}\n\t\tif pathArr[2]+\"/\"+pathArr[3] == `web/plugin` && len(webPlugin) == 0 {\n\t\t\twebPlugin = filepath.Join(pathArr[0], pathArr[1], pathArr[2], pathArr[3])\n\t\t}\n\t}\n\tif len(serverPlugin) == 0 && len(webPlugin) == 0 {\n\t\tzap.L().Error(\"非标准插件，请按照文档自动迁移使用\")\n\t\treturn webIndex, serverIndex, errors.New(\"非标准插件，请按照文档自动迁移使用\")\n\t}\n\n\tif len(serverPlugin) != 0 {\n\t\tif serverPackage == \"\" {\n\t\t\tserverPackage = serverRootName\n\t\t}\n\t\terr = installation(serverPlugin, global.GVA_CONFIG.AutoCode.Server, global.GVA_CONFIG.AutoCode.Server)\n\t\tif err != nil {\n\t\t\treturn webIndex, serverIndex, err\n\t\t}\n\t\terr = ensurePluginRegisterImport(serverPackage)\n\t\tif err != nil {\n\t\t\treturn webIndex, serverIndex, err\n\t\t}\n\t}\n\n\tif len(webPlugin) != 0 {\n\t\terr = installation(webPlugin, global.GVA_CONFIG.AutoCode.Server, global.GVA_CONFIG.AutoCode.Web)","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/flipped-aurora/gin-vue-admin/blob/3136500ef380842b0eb6c4daa87c3f8a47fcf9e0/server/service/system/auto_code_plugin.go#L98-L134","documentation":"Install scans the uploaded plugin archive for a directory ending at 'server/plugin' and 'web/plugin' paths. If neither is found, the archive layout does not match the required plugin structure (server/plugin/<name> and/or web/plugin/<name> at those depths), so it logs and returns this error telling the author to repackage per the plugin documentation.","triggerScenarios":"Uploading a plugin zip whose inner folders are not exactly .../server/plugin and .../web/plugin at the expected path depth (arr[1]/arr[2]/arr[2]/arr[3] style), e.g. zip created from the wrong root directory, extra wrapper folder, or a backend-only plugin archived with a nested 'myplugin/server/plugin' prefix of wrong length.","commonSituations":"Compressing the plugin folder itself instead of its contents; renamed top-level directories; plugins built against older layout conventions; manually restructured zips.","solutions":["Repackage the zip so it contains server/plugin/<name>/ and web/plugin/<name>/ at the correct relative depths — zip from the parent of 'server'/'web'.","Verify the archive by listing it: unzip -l plugin.zip should show paths ending in server/plugin/<name>/ and web/plugin/<name>/.","If the plugin is intentionally non-standard, install it manually by copying folders into server/plugin/ and web/src/plugin/ instead of using auto-install.","Follow aiDoc/modules/plugin-development.md directory conventions when building the plugin."],"exampleFix":"// before (zip root contains plugin files directly)\nmyplugin/main.go\nmyplugin/api/...\n// after (standard layout, zip from parent dir)\nserver/plugin/myplugin/main.go\nweb/src/plugin/myplugin/index.js","handlingStrategy":"validation","validationCode":"const entries = await listZipPaths(zipFile)\nconst hasServer = entries.some(p => /(^|\\/)server\\/plugin\\/[^/]+\\//.test(p))\nconst hasWeb = entries.some(p => /(^|\\/)web\\/plugin\\/[^/]+\\//.test(p))\nif (!hasServer && !hasWeb) {\n  throw new Error('非标准插件，请按照文档自动迁移使用')\n}","typeGuard":null,"tryCatchPattern":"webIndex, serverIndex, err := pluginService.Install(file)\nif err != nil && strings.Contains(err.Error(), \"非标准插件\") {\n    return fmt.Errorf(\"插件包缺少 server/plugin 或 web/plugin 目录结构，请重新打包: %w\", err)\n}","preventionTips":["Always zip from the directory containing 'server/' and 'web/', not from inside them.","Validate the zip listing against the documented layout before upload.","Use the official plugin template (aiDoc/modules/plugin-development.md) so structure is guaranteed."],"tags":["plugin","archive-layout","autocode"],"backgroundTag":"invalid-archive-structure","analyzedSha":"3136500ef380842b0eb6c4daa87c3f8a47fcf9e0","analyzedAt":"2026-08-31T13:50:02.721Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}