multica-ai/multica · error
plugin directory %q is not empty
Error message
plugin directory %q is not empty
What it means
Guard in `multica plugin init <dir>` (cmd_plugin.go:82): os.ReadDir on the cleaned target directory succeeded and returned at least one entry, so the scaffolder refuses to run to avoid overwriting existing files. This is a deliberate safety check, not an environment failure.
Source
Thrown at server/cmd/multica/cmd_plugin.go:82
pluginInitCmd.Flags().String("key", "dev.local.example-skill", "Reverse-DNS Plugin key")
pluginInitCmd.Flags().String("name", "Example Skill", "Plugin and Skill display name")
pluginInitCmd.Flags().String("publisher", "private.local", "Private publisher label")
pluginValidateCmd.Flags().String("output", "json", "Output format: table or json")
pluginPackCmd.Flags().String("output", "", "Output ZIP path (required)")
pluginPackCmd.Flags().String("format", "table", "Result format: table or json")
pluginInstallCmd.Flags().String("workspace", "", "Workspace ID, slug, or ID prefix")
pluginInstallCmd.Flags().String("output", "json", "Output format: table or json")
pluginListCmd.Flags().String("workspace", "", "Workspace ID, slug, or ID prefix")
pluginListCmd.Flags().String("output", "table", "Output format: table or json")
pluginStatusCmd.Flags().String("workspace", "", "Workspace ID, slug, or ID prefix")
pluginStatusCmd.Flags().String("output", "json", "Output format: table or json")
}
func runPluginInit(cmd *cobra.Command, args []string) error {
dir := filepath.Clean(args[0])
entries, err := os.ReadDir(dir)
if err == nil && len(entries) > 0 {
return fmt.Errorf("plugin directory %q is not empty", dir)
}
if err != nil && !os.IsNotExist(err) {
return fmt.Errorf("inspect plugin directory: %w", err)
}
key, _ := cmd.Flags().GetString("key")
name, _ := cmd.Flags().GetString("name")
publisher, _ := cmd.Flags().GetString("publisher")
manifest := plugincontract.Manifest{
APIVersion: plugincontract.APIVersionV1,
Kind: plugincontract.KindPlugin,
Metadata: plugincontract.Metadata{
Key: key, Name: name, Description: "A workspace-private declarative Skill Plugin.", Version: "0.1.0", Publisher: publisher,
},
Compatibility: plugincontract.Compatibility{
HostAPI: ">=1.0.0 <2.0.0",
RequiredDaemonFeatures: []string{
plugincontract.DaemonFeatureExecutionManifestV1,
plugincontract.DaemonFeatureAgentSkillV1,View on GitHub (pinned to 2c0912b6ec)
Solutions
- Point init at a fresh, truly empty directory: `multica plugin init ./my-plugin-v2`.
- If the existing content is disposable, remove it first: `rm -rf ./my-plugin && multica plugin init ./my-plugin`.
- If only hidden OS files block it, delete those specifically (`find ./my-plugin -name '.DS_Store' -delete`) and retry.
Example fix
// before multica plugin init ./my-plugin # dir already has plugin.yaml from earlier run // plugin directory "/abs/my-plugin" is not empty // after rm -rf ./my-plugin multica plugin init ./my-plugin --key com.example.my-plugin --name "My Plugin"
Defensive patterns
Strategy: validation
Validate before calling
entries, err := os.ReadDir(dir)
if err == nil && len(entries) > 0 {
// refuse or clean before calling plugin init
if !force { return fmt.Errorf("refusing: %s not empty", dir) }
if err := os.RemoveAll(dir); err != nil { return err }
} Prevention
- Always scaffold into a brand-new directory name.
- Check emptiness yourself (including hidden files) before re-running init.
- Treat a failed init as resumable by deleting the partial directory first.
When it happens
Trigger: Running `multica plugin init ./my-plugin` when ./my-plugin already contains any file or subdirectory (even dotfiles like .DS_Store or .git).
Common situations: Re-running init after a previous partial scaffold; pointing at an existing source folder; OS artifacts (Thumbs.db, .DS_Store) inside a directory the user believes is empty.
Related errors
- plugin source %q is not a directory or regular ZIP
- --%s-file %q: empty contents%s
- inspect plugin directory: %w
- plugin archive exceeds %d bytes
- validate Plugin: %w
AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15).
Data as JSON: /api/errors/2fabb3de7c098247.
Report an issue: GitHub.