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

  1. Verify the archive contains `server/plugin/<name>` and/or the corresponding web plugin directory with the expected folder structure.
  2. Re-export the plugin package using the standard plugin packaging flow.
  3. Check that you uploaded the correct .zip file and that it is not truncated (test by extracting locally).
  4. 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

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


AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31). Data as JSON: /api/errors/0dafe512a73b7c24. Report an issue: GitHub.