Skills
Claude Code skill anti-patterns to avoid
Skills that hijack unrelated prompts, repeat Claude's defaults, leak secrets, or assume unavailable tools break reliability. Follow structured patterns: narrow descriptions, explicit scopes, and declarative tool dependencies.
Claude Code skills are structured files that extend Claude’s capabilities by teaching it to recognize and execute specialized workflows. A skill lives in ~/.claude/skills/ (or in the .claude/skills/ directory of a project) and contains metadata (name, description, triggers) plus implementation logic. The skill file acts as a contract: when the user’s input matches the description, Claude activates the skill; when it doesn’t, the skill stays dormant. This routing mechanism is powerful but fragile. Common mistakes turn skills into noise that hijacks unrelated conversations, duplicates work Claude already does, leaks secrets, or fails silently when tools aren’t installed.
This post identifies the most frequent anti-patterns and shows concrete before/after fixes.
Anti-Pattern 1: Overbroad or vague descriptions that hijack unrelated prompts
The most common failure is a description that matches too many user requests. When Claude’s routing engine sees a loose description, it activates the skill even for tangential or unrelated tasks.
Bad example:
name: DataProcessor
description: Handles data processing and analysis tasks
This description will activate for “analyze my survey results,” “clean this spreadsheet,” “load a CSV,” and “find outliers in my dataset.” The skill becomes a catch-all that consumes the user’s real intent.
Better example:
name: CSVtoParquetConverter
description: Converts CSV files to Apache Parquet format, handling schema inference and compression
triggers:
- "convert CSV to Parquet"
- "export data to Parquet"
The tighter description reduces false activations. The triggers field (supported in Anthropic’s skill format) makes intent even more explicit. Claude will activate this skill only when the user explicitly asks for a CSV-to-Parquet conversion, not for every data task.
Anti-Pattern 2: Duplicating default Claude capabilities
Skills are most valuable when they teach Claude something it cannot do alone. If your skill merely wraps a task Claude handles natively, you waste a skill slot and add latency.
Bad example:
name: JSONParser
description: Parses and validates JSON
implementation: |
Parse the provided JSON string and return the result
Claude can parse JSON without a skill. This duplicates built-in capability and adds nothing.
Better approach: First test your task against baseline Claude. If Claude solves it in 1-2 turns without the skill, don’t make a skill. If the task requires:
- Integration with a local tool (e.g., kubectl, ffmpeg, a company CLI)
- Fetching data from a private API or database
- Applying a company-specific schema or workflow
- Repeating the same multi-step process across many conversations
Then a skill is justified. Example:
name: DeploymentHelper
description: Deploys Docker images to your Kubernetes cluster using kubectl, with rollback on failure
triggers:
- "deploy to production"
- "roll back deployment"
dependencies:
- kubectl
- docker
implementation: |
Execute kubectl apply, monitor rollout status, and rollback if the deployment fails health checks.
This skill teaches Claude your deployment workflow and integrates with tools not available to baseline Claude.
Anti-Pattern 3: Embedding secrets, API keys, or private paths in skill files
Skills are often committed to version control, shared with teammates, or visible in logs. Hardcoding secrets is a critical security error.
Bad example:
name: DatabaseQuery
description: Queries the production database
implementation: |
Connect to postgresql://user:password123@prod-db.company.com:5432/main
Execute the following SQL query...
Any teammate with access to the repo, or any log aggregation system, now sees the credentials.
Better example:
name: DatabaseQuery
description: Queries the company PostgreSQL database using credentials from environment
implementation: |
Retrieve the DB_HOST, DB_USER, and DB_PASSWORD from environment variables.
If any are missing, instruct the user to run: export DB_HOST=... export DB_USER=... export DB_PASSWORD=...
Connect to $DB_HOST and execute the query.
security_note: |
Never hardcode credentials. Use environment variables or a secrets manager.
Alternatively, document that the user must configure secrets via their system’s credential store (.aws/credentials, ~/.kube/config, KUBECONFIG, etc.) before invoking the skill.
Anti-Pattern 4: Assuming tools or dependencies are installed
Skills often invoke external binaries (kubectl, Node.js, Python packages, custom CLIs). If the user’s environment lacks these tools, the skill fails cryptically or hangs.
Bad example:
name: KubernetesDeployer
description: Deploys applications to Kubernetes
implementation: |
Run: kubectl apply -f deployment.yaml
Check rollout: kubectl rollout status deployment/app
If the user doesn’t have kubectl installed, Claude attempts the command and fails. The skill provides no guidance on fixing the environment.
Better example:
name: KubernetesDeployer
description: Deploys applications to Kubernetes
dependencies:
- kubectl (v1.20+)
- kubeconfig configured
implementation: |
Before proceeding, verify that kubectl is installed and kubeconfig is set.
If kubectl is not found or kubeconfig is not readable, provide the user with:
- Installation instructions: https://kubernetes.io/docs/tasks/tools/
- Configuration guide: https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/
Then execute: kubectl apply -f deployment.yaml
Check rollout: kubectl rollout status deployment/app
Explicitly declaring dependencies in metadata and adding fallback instructions (check, inform, guide) makes the skill resilient.
Comparison of skill design patterns
| Design aspect | Anti-pattern | Best practice |
|---|---|---|
| Description | ”Handles all data work” (5+ possible intents) | “Converts CSV to Parquet format” (1 intent) |
| Scope | Covers a broad tool (e.g., “SQL”) | Covers a narrow, specific workflow (e.g., “Query production DB with schema validation”) |
| Duplication | Repeats Claude’s native JSON parsing | Teaches Claude a custom company schema or a tool integration Claude cannot do alone |
| Secrets | Hardcoded API keys in implementation | Environment variables or documented secure credential sources |
| Dependencies | Assumes kubectl is installed | Declares dependencies, checks for them, provides install/config guidance |
| Triggers | None; relies on description matching | Explicit list of phrases the user is likely to say |
How to audit and fix existing skills
Review each skill in your ~/.claude/skills/ directory:
- Test description narrowness: Ask yourself, “How many different user requests would trigger this skill?” If the answer is more than 2-3, narrow the description.
- Check for duplication: Run the skill’s core task through baseline Claude. If Claude solves it without the skill, consider removing the skill or narrowing its scope.
- Search for secrets: Grep the skill file for
password,key,secret,token. If any exist, move them to environment variables. - List dependencies: Note every external tool (kubectl, Node.js, ffmpeg, custom CLI) and add a check in the implementation that verifies each one before use.
- Document triggers explicitly: Add a
triggersfield listing the exact phrases that should activate the skill.
Takeaways
Effective Claude Code skills are narrow, single-purpose, and teach Claude something it cannot do alone. Overbroad descriptions and duplicate capabilities waste skill slots and confuse the routing system. Hardcoded secrets and missing dependency checks create security and reliability debt. Audit your skills against these patterns: explicit descriptions, single intent per skill, no embedded credentials, and declarative dependencies with fallback guidance.
Further reading
- Anthropic Claude Code documentation covers the skill file format and routing behavior.
- Anthropic skills repository contains examples of well-structured skills.
- Claude capabilities overview describes what Claude can do natively, helping you identify when a skill is genuinely necessary.
- OWASP Secrets Management guide outlines best practices for handling credentials in code.
- Kubernetes kubectl installation guide is a reference example for documenting tool dependencies clearly.
Frequently asked
What is a Claude Code skill and how does it differ from a prompt instruction?
A skill is a structured YAML or JSON file in ~/.claude/skills/ that tells Claude Code when and how to trigger specific capabilities. Unlike inline instructions, skills use a frontmatter pattern with name, description, and file paths, and they integrate with Claude's routing system to activate only when relevant. This prevents token waste and scope creep.
Why does an overbroad skill description break unrelated conversations?
Claude Code uses skill descriptions to route user input. A description like 'handles all data work' matches nearly every request, causing the skill to activate when the user asks about unrelated tasks. Narrow descriptions (e.g., 'converts CSV to Parquet') reduce false activations and preserve context for other tools.
How do I avoid duplicating Claude's built-in capabilities in a skill?
Check Anthropic's Claude capabilities docs and test your skill against baseline Claude first. If Claude solves the task without the skill, either remove the skill or make it narrowly specialized (e.g., a company-specific data schema instead of generic JSON parsing). Duplication wastes skill slots and slows activation.
What should I do if a skill needs a tool that might not be installed?
Declare tool dependencies explicitly in the skill metadata or frontmatter, and add a fallback instruction in the skill body that tells Claude to check installation and provide setup steps if needed. Never assume kubectl, Node.js, or custom CLIs exist without verification.
Why shouldn't I store API keys or credentials in skill files?
Skill files are often version-controlled or shared across teams. Hardcoding secrets risks exposure and violates security policy. Use environment variables, a secure secrets manager, or refer users to set credentials via Claude's context or authenticated configuration instead.