How to Handle Errors and Failures in Claude Plugins: A Complete Guide
Claude plugins handle errors through explicit manifest declarations in .claude-plugin/marketplace.json, exponential back-off retry policies, and structured JSON error messages that allow the LLM to degrade gracefully or retry failed operations.
Robust error handling is essential when building Claude plugins, as failures in external API calls or file operations can interrupt a developer’s workflow inside the Claude Code environment. The anthropics/claude-plugins-community repository establishes a comprehensive error-handling architecture that requires plugins to declare failure modes up front, implement automatic retries, and communicate issues through machine-parseable formats. By following these patterns, plugin authors ensure that transient network issues and invalid inputs are managed without aborting the entire session.
Declare Error Contracts in the Plugin Manifest
Every plugin must define its error handling behavior in the central manifest at .claude-plugin/marketplace.json. This file contains an errorHandling field that specifies retry policies, logging formats, and user message templates for the entire plugin ecosystem.
The manifest structure includes:
- retryPolicy: Controls
maxAttempts,initialDelayMs, andbackoffFactorfor transient failures - structuredLogging: Boolean flag enabling machine-parseable error output
- userMessageTemplate: Template string for formatting human-readable diagnostics
{
"name": "example-plugin",
"version": "0.1.0",
"description": "Demo plugin showing error handling.",
"errorHandling": {
"retryPolicy": {
"maxAttempts": 3,
"initialDelayMs": 500,
"backoffFactor": 2
},
"structuredLogging": true,
"userMessageTemplate": "❗️ {errorCode}: {message}\nTry: {suggestion}"
}
}
This declaration pattern is implemented in the security-hardening-and-production-grade-error-handling plugin description within the marketplace manifest, providing a reference implementation for all community plugins.
Implement Retry Logic with Exponential Back-Off
Transient failures such as network timeouts or rate limits require automatic retry mechanisms. The repository recommends implementing exponential back-off in skill scripts, matching the parameters declared in the manifest's retryPolicy.
The following Python implementation mirrors the retry logic used by the sentry-error-assistant plugin documented at lines 17574–17575:
import time
import requests
def call_external_api(payload):
attempts = 0
delay = 0.5 # seconds, matches initialDelayMs
while attempts < 3:
try:
r = requests.post(
"https://api.example.com/do",
json=payload,
timeout=5
)
r.raise_for_status()
return r.json()
except (requests.Timeout, requests.ConnectionError) as e:
attempts += 1
if attempts == 3:
raise RuntimeError(
"ERR_NETWORK",
"Failed after 3 attempts – check your connection."
) from e
time.sleep(delay)
delay *= 2 # exponential back-off
This pattern ensures that temporary network hiccups do not immediately fail the developer's request, giving external services time to recover between attempts.
Return Structured Error Objects for User Diagnostics
When failures are not resolvable through retries, plugins must return structured error objects that Claude can parse and present to users. The tres-finance-plugin demonstrates this pattern in tres-finance-plugin/README.md at line 96 when validating CSV uploads.
Format errors as JSON objects containing code, message, and suggestion fields:
{
"error": {
"code": "ERR_INVALID_CSV",
"message": "Missing required column 'Organizational Wallet'.",
"suggestion": "Upload a CSV with the exact header names shown in the template."
}
}
This structure allows the LLM to understand the specific failure mode and either request corrected input from the user or attempt an alternative approach automatically, maintaining workflow continuity.
Configure Graceful Degradation in CI Workflows
The repository supports graceful degradation through the scope-errors-to-changed flag in .github/actions/validate-plugins/action.yml. When enabled, this setting converts validation errors on unchanged plugin entries into warnings, preventing CI failures for legacy code while maintaining strict standards for new modifications.
Configuration example from the CI workflow:
# .github/actions/validate-plugins/action.yml
inputs:
scope-errors-to-changed:
description: "Downgrade errors on unchanged entries to warnings."
required: false
default: "false"
As documented in .github/actions/validate-plugins/README.md at line 116, this flag allows the validation suite to distinguish between critical invariant violations and non-blocking issues, ensuring that only relevant failures block pull requests.
Test Failure Paths with the Health Skill
The testdino suite provides a "health" skill that validates error handling across all plugin entry points. Located in testdino/README.md, this test framework verifies that plugins correctly log errors and surface them to the user interface.
Plugin authors should include test cases covering:
- Invalid input parameters
- Missing file references
- Network timeout scenarios
- Malformed API responses
Running these validation checks ensures that error handling logic functions correctly before deployment to the Claude Code environment, preventing runtime failures in production workflows.
Summary
- Declare all possible error states in
.claude-plugin/marketplace.jsonusing theerrorHandlingfield with explicitretryPolicyconfigurations - Implement exponential back-off in Python skill scripts to handle transient network failures automatically
- Return structured JSON error objects containing
code,message, andsuggestionfields for machine-parseable diagnostics - Enable
scope-errors-to-changedin CI workflows to allow graceful degradation when validating unchanged plugin entries - Use the
testdinohealth skill to verify that all failure paths log correctly and surface user-friendly messages
Frequently Asked Questions
What file defines the error handling configuration for Claude plugins?
The .claude-plugin/marketplace.json file defines the central error handling configuration for all plugins in the repository. This manifest includes the errorHandling object, which specifies retry policies, structured logging preferences, and user message templates. Each plugin entry in this file must declare its failure modes explicitly according to the schema shown in the security-hardening-and-production-grade-error-handling plugin description.
How does the repository handle transient network failures in plugin operations?
Transient failures are handled through automatic retries with exponential back-off, as defined in the retryPolicy object within each plugin's manifest. The policy specifies maxAttempts, initialDelayMs, and backoffFactor values that skill scripts implement in their exception handling logic. For example, the sentry-error-assistant plugin uses this pattern to retry API calls up to three times with doubling delays between attempts before surfacing a permanent error to the user.
Can Claude plugins return warnings instead of hard errors?
Yes, plugins can configure graceful degradation through the scope-errors-to-changed input in .github/actions/validate-plugins/action.yml. When set to "true", this flag instructs the CI validation workflow to downgrade errors on unchanged plugin entries to warnings, allowing the session to continue with partial results. This mechanism is documented in .github/actions/validate-plugins/README.md and prevents legacy plugin issues from blocking new development while maintaining strict validation standards for modified code.
What format should structured error messages follow?
Structured error messages must follow a JSON format containing an error object with code, message, and suggestion fields. This format, demonstrated in the tres-finance-plugin at line 96 of its README, allows Claude to parse the specific error type and remediation steps programmatically. The structuredLogging flag in the plugin manifest must be set to true to enable this output format across all plugin operations.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →