flipped-aurora/gin-vue-admin · error
parent plugin is not a directory
Error message
parent plugin is not a directory
What it means
When installing a sub-plugin under a parent plugin, the installer resolves the parent's directory on disk and stats it. If the parent path exists but is a file (or symlink to a file) rather than a directory, it cannot host a subPlugin folder, so this error is thrown.
Source
Thrown at server/service/system/auto_code_plugin.go:325
}
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() {
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 {View on GitHub (pinned to 3136500ef3)
Solutions
- Inspect the parent plugin path on disk and remove or rename the stray file that occupies the plugin name.
- Re-clone or restore the parent plugin directory from source so it exists as a proper directory.
- Verify the parentPlugin name passed to the install API is spelled correctly (exact case).
- Ensure the plugin root directory in AutoCode.Server config points to the intended component tree.
Example fix
// before (on disk) server/plugin/parent-plugin <- plain file // after mkdir server/plugin/parent-plugin # restore plugin contents (plugin.go, etc.) server/plugin/parent-plugin/plugin.go
Defensive patterns
Strategy: validation
Validate before calling
const st = fs.statSync(path.join(serverPluginRoot, parentPlugin))
if (!st.isDirectory()) throw new Error(`${parentPlugin} exists but is not a directory`) Try / catch
try {
await installSubPlugin(parent, child)
} catch (e) {
if (e.message.includes('not a directory')) {
showHint('Parent plugin path is occupied by a file; remove or rename it.')
} else { throw e }
} Prevention
- Never leave archives or temp files named like plugins inside the plugin root.
- Periodically audit the plugin root for stray files.
- Use consistent case when referencing plugin names to avoid case-sensitivity surprises.
When it happens
Trigger: Calling the sub-plugin install API with a parentPlugin name that collides with a regular file inside the component's plugin root (e.g. a stray `foo.zip` or a file named `foo` where the plugin directory should be).
Common situations: Leftover files accidentally named like a plugin; a plugin that was replaced by a tarball/zip left in place; path case-sensitivity mismatch causing Stat to hit a different file; corrupted checkout where the plugin directory was overwritten by a file.
Related errors
- plugin already exists
- server and web plugin names must match
- plugin archive contains multiple server plugins
- plugin archive contains multiple web plugins
- invalid plugin archive
AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31).
Data as JSON: /api/errors/2602d40cd2c38264.
Report an issue: GitHub.