# How Claude Plugins Enforce Shell-Safe Plugin Names: Validation Rules Explained

> Learn how Claude plugins enforce shell-safe plugin names using regex validation. Discover rules preventing shell metacharacters for consistent naming.

- Repository: [Anthropic/claude-plugins-community](https://github.com/anthropics/claude-plugins-community)
- Tags: deep-dive
- Published: 2026-08-31

---

**Claude plugins use a strict regex-based validation system that permits only lowercase alphanumerics and hyphens, preventing any shell metacharacters from entering the name field.**

Plugin names in the `anthropics/claude-plugins-community` repository must remain safe for command-line usage and filesystem operations. This article explains the two-layer enforcement mechanism that keeps **plugin names consistent** and free of dangerous characters.

## The Naming Constraint: Character Set and Pattern

Every plugin declares its identity through a `"name"` field in its manifest file. The repository enforces a rigid pattern that eliminates ambiguity in shell contexts.

The permitted pattern is defined by this regular expression:

```regex
^[a-z0-9][a-z0-9-]*$

```

This regex imposes three rules:

- **Start character**: Must be a lowercase letter or digit
- **Body characters**: Only lowercase letters, digits, and hyphens allowed
- **Forbidden characters**: No spaces, no punctuation, no quotes, no brackets, no other shell metacharacters

The `quickdesign` plugin demonstrates a valid name in its manifest at [`quickdesign/.claude-plugin/plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/quickdesign/.claude-plugin/plugin.json):

```json
{
  "name": "quickdesign",
  "display_name": "QuickDesign",
  "description": "Visual UI for Claude Code plugins."
}

```

## Layer 1: Manifest Declaration

Plugin authors define the name in the **plugin manifest** located at [`.claude-plugin/plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.claude-plugin/plugin.json) within each plugin directory. This file serves as the canonical source of truth for the plugin's identifier.

The manifest separates concerns cleanly:

- **`name`**: The machine-readable identifier (strictly validated)
- **`display_name`**: The human-readable label (no restrictions)

This separation allows user-friendly presentation while maintaining **shell-safe plugin names** for technical operations.

## Layer 2: CI Validation Script

The repository's **Validate Plugins** workflow runs automatically on every contribution. The critical validation logic lives in [`.github/actions/validate-plugins/scripts/20-validate-cli-marketplace.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/validate-plugins/scripts/20-validate-cli-marketplace.sh).

The script extracts and validates each plugin name:

```bash

# In 20-validate-cli-marketplace.sh

PLUGIN_NAME=$(jq -r .name "$PLUGIN_DIR/.claude-plugin/plugin.json")

if [[ ! "$PLUGIN_NAME" =~ ^[a-z0-9][a-z0-9-]*$ ]]; then
    echo "❌ Invalid plugin name: $PLUGIN_NAME"
    exit 1
fi

```

The workflow file at [`.github/workflows/validate-plugins.yml`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/workflows/validate-plugins.yml) orchestrates this check. Any submission with an invalid name triggers an immediate CI failure, blocking the merge.

## Why Shell Metacharacters Are Excluded

The **plugin name consistency** rules exist to prevent common shell injection and parsing vulnerabilities. Prohibited characters include:

| Character Category | Examples | Risk |
|---|---|---|
| Whitespace | space, tab | Word splitting in shell commands |
| Quotes | `"`, `'` | String termination attacks |
| Brackets | `[`, `]`, `{`, `}` | Glob expansion and command grouping |
| Redirection | `>`, `<`, `|` | File overwrite and pipeline injection |
| Variable expansion | `$`, `` ` `` | Command substitution attacks |
| Wildcards | `*`, `?` | Unintended file matching |
| Other punctuation | `;`, `&`, `!` | Command sequencing and history expansion |

The hyphen exception is safe because it holds no special meaning when positioned between alphanumeric characters.

## Validation in Practice

A plugin author attempting to use an invalid name would encounter this CI output:

```bash
❌ Invalid plugin name: my_plugin

# Fails because underscore is not in [a-z0-9-]

❌ Invalid plugin name: 2cool4u!

# Fails because '!' is prohibited

❌ Invalid plugin name: MyPlugin

# Fails because uppercase 'M' is prohibited

```

The validation is case-sensitive and position-sensitive. A name starting with a hyphen would also fail, as the regex requires an alphanumeric first character.

## Summary

- **Plugin names** in Claude's community repository follow a strict `^[a-z0-9][a-z0-9-]*$` pattern
- The **plugin manifest** at [`.claude-plugin/plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.claude-plugin/plugin.json) declares the canonical name
- **CI validation** in [`20-validate-cli-marketplace.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/20-validate-cli-marketplace.sh) enforces the regex before any merge
- This dual-layer system guarantees **shell-safe plugin names** across the entire ecosystem

## Frequently Asked Questions

### What happens if my plugin name contains an uppercase letter?

The CI validation rejects it. The regex `^[a-z0-9][a-z0-9-]*$` explicitly permits only lowercase letters. Convert your name to lowercase—for example, use `"myplugin"` instead of `"MyPlugin"`.

### Are underscores allowed in Claude plugin names?

No. The character set is strictly limited to lowercase letters, digits, and hyphens. Use hyphens as word separators: `"my-plugin"` rather than `"my_plugin"`.

### Where can I see the validation script in action?

Examine the workflow file at [`.github/workflows/validate-plugins.yml`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/workflows/validate-plugins.yml) and the validation logic at [`.github/actions/validate-plugins/scripts/20-validate-cli-marketplace.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/validate-plugins/scripts/20-validate-cli-marketplace.sh). These run automatically on every pull request to the `anthropics/claude-plugins-community` repository.

### Why restrict names when the display_name can be anything?

The `name` field appears in filesystem paths, CLI commands, and API calls where shell safety matters. The `display_name` handles user-facing presentation without these constraints, giving authors flexibility while preserving technical reliability.