# Common Pitfalls in Claude Plugin Development: 10 Critical Mistakes to Avoid

> Avoid common pitfalls in Claude plugin development. Learn to fix malformed manifests, unsynchronized metadata, and unhandled exceptions to improve user experience and prevent session termination.

- Repository: [Anthropic/claude-plugins-community](https://github.com/anthropics/claude-plugins-community)
- Tags: best-practices
- Published: 2026-09-10

---

**The most frequent pitfalls in Claude plugin development stem from malformed [`plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/plugin.json) manifests, unsynchronized marketplace metadata, missing user confirmation hooks for destructive operations, and unhandled exceptions in tool hooks that terminate Claude sessions.**

Developing plugins for Claude requires strict adherence to a manifest-driven architecture maintained in the `anthropics/claude-plugins-community` repository. While reference implementations like `quickdesign` and `tres-finance-plugin` demonstrate best practices, developers often encounter automated validation failures or runtime crashes due to subtle configuration errors. Understanding these **common pitfalls in Claude plugin development** helps ensure your plugin passes the CI pipeline in [`.github/workflows/validate-plugins.yml`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/workflows/validate-plugins.yml) and operates safely in production.

## Configuration and Manifest Errors

The foundation of every Claude plugin rests in its [`.claude-plugin/plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.claude-plugin/plugin.json) manifest. According to the source code analysis, the majority of validation failures occur when this file is incomplete or malformed.

### Missing Required Fields in plugin.json

The manifest must contain every mandatory key: `name`, `version`, `description`, `author`, `homepage`, `repository`, `license`, and `keywords`. Missing any field causes the marketplace validator to reject the submission immediately. The [`quickdesign/.claude-plugin/plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/quickdesign/.claude-plugin/plugin.json) file serves as the canonical reference, containing all required fields in the correct JSON structure.

```json
{
  "name": "my-plugin",
  "version": "0.1.0",
  "description": "Brief description of what the plugin does.",
  "icon": "./icon.svg",
  "author": {
    "name": "Your Name",
    "url": "https://your-website.example"
  },
  "homepage": "https://github.com/your-org/your-plugin",
  "repository": "https://github.com/your-org/your-plugin",
  "license": "MIT",
  "keywords": ["ai", "plugin", "example"]
}

```

### Version Synchronization Failures

When submitting to the community marketplace, the `name` and `version` fields must match exactly between [`plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/plugin.json) and [`marketplace.json`](https://github.com/anthropics/claude-plugins-community/blob/main/marketplace.json). The CI workflow defined in [`.github/workflows/validate-plugins.yml`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/workflows/validate-plugins.yml) explicitly flags discrepancies between these files as errors. Maintain synchronization by updating both files simultaneously or using automated version bumping scripts.

### Broken Asset References

The `icon` field requires a relative path to an SVG file stored alongside the manifest. If the file is missing or the path is incorrect—such as referencing `icon.svg` when the file is actually stored at `quickdesign/.claude-plugin/icon.svg` with a different case—the Claude UI displays a broken image. Always verify the relative path resolves correctly from the plugin root.

### Undeclared Permissions and Version Mismatches

Plugins accessing the filesystem or external APIs must explicitly declare permissions in [`plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/plugin.json). Additionally, version mismatches between the plugin manifest and individual skill files create confusion. The repository tracks skill-specific versions using files like `quickdesign/skills/quickdesign/.version`, which should always align with the root manifest.

## Skill Definition Schema Violations

Each skill requires a properly formatted [`SKILL.md`](https://github.com/anthropics/claude-plugins-community/blob/main/SKILL.md) file following a strict markdown schema.

### Invalid Markdown Structure

The skill definition must include specific sections: trigger commands, description, usage examples, and parameter definitions. Files like [`tres-finance-plugin/skills/tres-wallets-upload/SKILL.md`](https://github.com/anthropics/claude-plugins-community/blob/main/tres-finance-plugin/skills/tres-wallets-upload/SKILL.md) demonstrate the required layout. Typos in section headers or missing fields cause runtime errors when Claude attempts to invoke the skill.

```markdown

# Skill: /my-plugin:my-action  

**Description**  
Performs X operation on Y resource.  

**Usage**  

```bash
/my-plugin:my-action --param1 <value> --param2 <value>

```  

**Parameters**  
- `--param1` – description (required)  
- `--param2` – description (optional)  

**Confirmation**  
Writes are gated behind a confirmation step; the skill will ask:  
> "Do you want to proceed with X on Y?"  

**Error handling**  
All network calls are wrapped in try/catch; failures return a concise error message.

```

## Security and Compliance Failures

The `anthropics/claude-plugins-community` repository enforces strict security standards through automated scanning.

### Hardcoded Secrets and API Keys

The CI pipeline includes a security scan in [`.github/actions/validate-plugins/scripts/00-detect-changes.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/validate-plugins/scripts/00-detect-changes.sh) that rejects any plugin containing hardcoded secrets. Never commit API keys, tokens, or credentials in your plugin code. Instead, access sensitive values through environment variables exclusively.

### Unpinned Dependencies

The validation workflow requires all external marketplace entries to pin specific commit SHAs rather than mutable branches. Failing to specify `"sha": "<commit SHA>"` in [`marketplace.json`](https://github.com/anthropics/claude-plugins-community/blob/main/marketplace.json) causes the CI to reject your submission, as unversioned dependencies introduce breaking changes. Always update the SHA only after thorough testing.

## Runtime Safety and Error Handling

Beyond validation, plugins must handle execution safely to prevent session crashes.

### Missing User Confirmation for Write Operations

Write-heavy plugins, particularly those interfacing with financial systems like `tres-finance-plugin`, must implement explicit user confirmation before executing destructive operations. Skipping this guardrail leads to accidental data mutations and marketplace rejection. Implement a `/confirm` hook that prompts users before proceeding with mutations.

### Unhandled Exceptions in Hooks

Pre-tool and post-tool hooks that raise uncaught exceptions abort the entire Claude session. This frequently occurs when developers assume network requests always succeed. Wrap all I/O operations in try/catch blocks and return structured error messages rather than allowing raw exceptions to propagate.

```python
def call_external_api(payload):
    # Prompt user for confirmation

    if not confirm("Proceed with API call to https://api.example.com?"):
        return {"error": "User cancelled operation"}

    try:
        response = requests.post("https://api.example.com", json=payload, timeout=10)
        response.raise_for_status()
        return response.json()
    except requests.RequestException as exc:
        return {"error": f"API request failed: {exc}"}

```

## Summary

- Validate [`plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/plugin.json) against the `quickdesign` reference to ensure all required fields are present and JSON syntax is correct.
- Synchronize `name` and `version` fields between [`plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/plugin.json) and [`marketplace.json`](https://github.com/anthropics/claude-plugins-community/blob/main/marketplace.json) to pass CI validation in [`.github/workflows/validate-plugins.yml`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/workflows/validate-plugins.yml).
- Store icons using relative paths from the plugin root and verify file existence before submission.
- Follow the strict markdown schema for [`SKILL.md`](https://github.com/anthropics/claude-plugins-community/blob/main/SKILL.md) files as demonstrated in [`tres-finance-plugin/skills/tres-wallets-upload/SKILL.md`](https://github.com/anthropics/claude-plugins-community/blob/main/tres-finance-plugin/skills/tres-wallets-upload/SKILL.md).
- Declare all required permissions explicitly and avoid hardcoded secrets to pass the security scan in [`.github/actions/validate-plugins/scripts/00-detect-changes.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/validate-plugins/scripts/00-detect-changes.sh).
- Pin all external dependencies using specific commit SHAs in [`marketplace.json`](https://github.com/anthropics/claude-plugins-community/blob/main/marketplace.json).
- Implement user confirmation hooks for write operations and wrap all external I/O in comprehensive error handling.

## Frequently Asked Questions

### Why does my plugin fail validation with a "malformed manifest" error?

The marketplace validator requires every mandatory field in [`plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/plugin.json), including nested objects like `author` with `name` and `url` properties. Even minor JSON syntax errors, such as trailing commas, trigger rejection. Compare your manifest against [`quickdesign/.claude-plugin/plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/quickdesign/.claude-plugin/plugin.json) and run your JSON through a linter before committing.

### How do I properly version my plugin and its individual skills?

Maintain a root [`plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/plugin.json) version and update corresponding entries in [`marketplace.json`](https://github.com/anthropics/claude-plugins-community/blob/main/marketplace.json) simultaneously. For plugins with multiple skills, track skill-specific versions using files like `quickdesign/skills/quickdesign/.version` and ensure these align with the root manifest version to prevent runtime mismatches.

### What security checks does the Claude plugins repository enforce?

The CI pipeline scans for hardcoded secrets using [`00-detect-changes.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/00-detect-changes.sh), validates that all permissions are explicitly declared in [`plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/plugin.json), and verifies that external dependencies are pinned to specific commit SHAs. Write operations must include user confirmation hooks to prevent accidental data mutations.

### Why does my plugin crash Claude instead of showing an error message?

Uncaught exceptions in tool hooks immediately terminate the Claude session. You must wrap all external API calls, file system operations, and network requests in try/catch blocks (or equivalent error handling) and return structured error objects rather than raising exceptions.