flipped-aurora/gin-vue-admin · error

plugin already exists

Error message

plugin already exists

What it means

Before copying the sub-plugin into place, the installer checks that the destination directory (`<root>/<pluginName>`) does not already exist. If os.Stat succeeds, meaning something already occupies the target path, the install is aborted to avoid overwriting an existing plugin.

Source

Thrown at server/service/system/auto_code_plugin.go:336

		return "", err
	}
	info, err := os.Stat(parentPath)
	if err != nil {
		return "", errors.Wrap(err, "parent plugin does not exist")
	}
	if !info.IsDir() {
		return "", errors.New("parent plugin is not a directory")
	}
	return utils.JoinWithinRoot(parentPath, "subPlugin")
}

func ensurePluginTargetAvailable(root, pluginName string) error {
	target, err := utils.JoinWithinRoot(root, pluginName)
	if err != nil {
		return err
	}
	if _, err = os.Stat(target); err == nil {
		return errors.New("plugin already exists")
	} else if !os.IsNotExist(err) {
		return err
	}
	return nil
}

func copyPluginArchive(sourceRoot, destinationRoot string) error {
	if err := os.MkdirAll(destinationRoot, 0755); err != nil {
		return err
	}
	return cp.Copy(sourceRoot, destinationRoot, cp.Options{Skip: skipMacSpecialDocument})
}

func prepareSubPluginSource(childPath, parentPlugin, childPlugin string) error {
	module := strings.TrimSpace(global.GVA_CONFIG.AutoCode.Module)
	if module == "" {
		return errors.New("autocode module is empty")
	}

View on GitHub (pinned to 3136500ef3)

Solutions

  1. Remove the existing directory at the target path if it is safe to delete (e.g. old version), then retry the install.
  2. Uninstall the existing sub-plugin through the normal uninstall flow before reinstalling.
  3. Rename the incoming sub-plugin (directory and module references) to a unique name and repackage.
  4. If a previous install partially failed, clean the leftover target directory manually first.

Example fix

// before
ls server/plugin/parent/subPlugin/child  # exists -> error
// after
rm -rf server/plugin/parent/subPlugin/child
# then retry the install API call
Defensive patterns

Strategy: validation

Validate before calling

const target = path.join(serverPluginRoot, parent, 'subPlugin', child)
if (fs.existsSync(target)) throw new Error(`sub-plugin target already exists: ${target}`)

Try / catch

try {
  await installSubPlugin(parent, child)
} catch (e) {
  if (e.message.includes('already exists')) {
    const ok = await confirm('Remove existing sub-plugin and reinstall?')
    if (ok) { await uninstallSubPlugin(parent, child); await installSubPlugin(parent, child) }
  } else { throw e }
}

Prevention

When it happens

Trigger: Installing a sub-plugin whose name already exists under the parent's `subPlugin` directory — either a previous install already placed it, or the user is re-running an install that partially completed, or another plugin happens to use the same name.

Common situations: Re-submitting the same install request twice; installing a different version of the same sub-plugin without uninstalling the old one; name collision between two independently developed sub-plugins; leftover folder from a failed prior install that copied files before failing.

Related errors


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