flipped-aurora/gin-vue-admin · error
invalid plugin archive
Error message
invalid plugin archive
What it means
After scanning the archive, the installer requires at least one recognized plugin part (server or web). If neither a `server/<name>/` nor a web plugin directory was found in the extracted contents, the archive is deemed not a plugin package and this error is thrown.
Source
Thrown at server/service/system/auto_code_plugin.go:306
root: filepath.Join(tempDir, filepath.FromSlash(strings.Join(parts[:index+2], "/"))),
name: name,
}
if parts[index] == "server" {
if archive.server != nil && (archive.server.name != part.name || archive.server.root != part.root) {
return pluginArchive{}, errors.New("plugin archive contains multiple server plugins")
}
archive.server = part
} else {
if archive.web != nil && (archive.web.name != part.name || archive.web.root != part.root) {
return pluginArchive{}, errors.New("plugin archive contains multiple web plugins")
}
archive.web = part
}
break
}
}
if archive.server == nil && archive.web == nil {
return pluginArchive{}, errors.New("invalid plugin archive")
}
return archive, nil
}
func pluginInstallRoot(component, parentPlugin string) (string, error) {
root, err := utils.JoinWithinRoot(global.GVA_CONFIG.AutoCode.Root, component, "plugin")
if err != nil || parentPlugin == "" {
return root, err
}
parentPath, err := utils.JoinWithinRoot(root, parentPlugin)
if err != nil {
return "", err
}
info, err := os.Stat(parentPath)
if err != nil {
return "", errors.Wrap(err, "parent plugin does not exist")
}
if !info.IsDir() {View on GitHub (pinned to 3136500ef3)
Solutions
- Verify the archive contains `server/plugin/<name>` and/or the corresponding web plugin directory with the expected folder structure.
- Re-export the plugin package using the standard plugin packaging flow.
- Check that you uploaded the correct .zip file and that it is not truncated (test by extracting locally).
- Flatten any excessive nesting so the `server/` and web roots sit at the expected depths inside the archive.
Example fix
// before (flat, unrecognized layout) main.go package.json // after (recognized layout) server/plugin/my-plugin/ web/src/plugin/my-plugin/
Defensive patterns
Strategy: validation
Validate before calling
const hasServer = entries.some(e => /(^|\/)server\/[^/]+\//.test(e))
const hasWeb = entries.some(e => /(^|\/)web\/src\/plugin\/[^/]+\//.test(e))
if (!hasServer && !hasWeb) throw new Error('archive is not a plugin package: no server or web plugin directory found') Try / catch
try {
await installPlugin(file)
} catch (e) {
if (e.message.includes('invalid plugin archive')) {
showHint('Uploaded file does not follow the plugin archive layout; check its folder structure.')
} else { throw e }
} Prevention
- Confirm the file is the plugin export zip, not a docs or source snapshot.
- Extract locally and inspect the top-level layout before every upload.
- Ensure zip creation includes directory entries (some tools strip them).
When it happens
Trigger: Uploading a zip that does not follow the plugin layout — no directory path containing `server/` or the web plugin root pattern; uploading an arbitrary project zip, a source-only archive with flat structure, or an empty/corrupted archive whose entries were not matched.
Common situations: Wrong file uploaded (docs zip, source snapshot, release artifact of something else); archive built with paths that are too deeply nested or use unexpected root folder names; zip extracted with tools that stripped directory entries; testing the endpoint with a random file renamed to .zip.
Related errors
- server and web plugin names must match
- plugin archive contains multiple server plugins
- plugin archive contains multiple web plugins
- parent plugin is not a directory
- plugin already exists
AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31).
Data as JSON: /api/errors/0dafe512a73b7c24.
Report an issue: GitHub.