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

  1. Point init at a fresh, truly empty directory: `multica plugin init ./my-plugin-v2`.
  2. If the existing content is disposable, remove it first: `rm -rf ./my-plugin && multica plugin init ./my-plugin`.
  3. 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

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


AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15). Data as JSON: /api/errors/2fabb3de7c098247. Report an issue: GitHub.