[BUG] Claude Code does not report errors in custom slash commands in a user-friendly, useful form
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
I reformatted the front-matter for one of my custom slash commands to look like this:
---
description: >
Lorem ipsum
allowed-tools:
- Bash(git reset:*)
- Bash(git status:*)
- Bash(git diff:*)
- Bash(git diff --staged:*)
- Bash(git diff --cached:*)
- Bash(git branch:*)
- Bash(git log:*)
- Bash(git add:*)
- Bash(git commit:*)
- Bash(git commit --amend:*)
- Bash(git show:*)
---
Now Claude Code thinks my custom slash command doesn't have the permission to use any tools.
A related issue is reported in #4695.
What Should Happen?
As long as the front-matter is valid YAML, Claude Code should parse it correctly and respect it.
Error Messages/Logs
I asked CC to do some tasks and then call `/commit`:
● Now let me commit the current changes using the /commit slash command:
⎿ Error: Bash command permission check failed for pattern "!`
- `": Command appears to be an incomplete fragment (starts with flags)
⎿ Interrupted · What should Claude do instead?
I explicitly ran `/commit`:
> /commit
⎿ Error: Bash command permission check failed for pattern "!`git reset`": This command requires approval
Steps to Reproduce
Use this custom slash command:
~~~md
---
description: >
Create intelligent, well-structured commits for the Rust Book project
with automatic validation and project-aware categorization
allowed-tools:
- Bash(git reset:*)
- Bash(git status:*)
- Bash(git diff:*)
- Bash(git diff --staged:*)
- Bash(git diff --cached:*)
- Bash(git branch:*)
- Bash(git log:*)
- Bash(git add:*)
- Bash(git commit:*)
- Bash(git commit --amend:*)
- Bash(git show:*)
- Bash(just validate:*)
- Bash(cargo build:*)
- Bash(cargo run:*)
- Bash(filterdiff:*)
- Bash(command:*)
- Bash(cat:*)
- Bash(fmt:*)
- Read
- Grep
- Glob
- TodoWrite
---
Intelligent Commit Creation for Rust Book
Create well-structured commits for "Mastering Rust for Java Programmers" with automatic validation, smart categorization, and project-aware commit messages.
Context
- Track all untracked files that are not git ignored: !
git ls-files -z --others --exclude-standard | xargs -0 -r git add - Unstage all currently staged changes, but keep them in the working directory: !
git reset - Current git status: !
git status - Current git diff: !
git diff HEAD - Current branch: !
git branch --show-current - Recent commits: !
git log --oneline -10
Your Task
Based on the above context, commit the changes for this Rust programming book project.
- For complex multi-commit workflows, use the TodoWrite tool to track each commit you plan to make
- If all changes are related, commit them together with a single, clear commit message
- If there are multiple unrelated changes, stage and commit them separately with distinct commit messages
- If a single file contains multiple unrelated changes (different hunks):
- Check if
filterdiffis available:command -v filterdiff - If available, use
filterdiffto selectively stage hunks:
```bash
# Generate diff for the file
git diff HEAD -- <file> > /tmp/file.diff
# Extract specific hunks (e.g., hunks 1 and 3 for one commit)
filterdiff --hunks=1,3 /tmp/file.diff > /tmp/selected.diff
# Apply to staging area
git apply --cached /tmp/selected.diff
# Commit the selected hunks
git commit -m "..."
# Repeat for remaining hunks
```
- If
filterdiffis not available, inform the user that the file contains mixed changes and recommend installingpatchutilsor manually separating hunks usinggit add -p <file>
- Always verify staged changes with
git diff --stagedbefore committing - Ensure commit messages are concise yet descriptive, following best practices
- For non-trivial changes, always include a body explaining the what and why
Project Context
This Rust book uses:
- Typst files in
formats/typst/en_US/parts/- Book content - Code examples in
code/chap-XX/rust-examples/src/- Runnable Rust code - Build system with
justfileandCargo.toml- Build automation - Documentation in
CLAUDE.md,README.md- Project guidelines - Spiral Learning System - Progressive pedagogical approach
- Target audience - Java programmers learning Rust
Commit Message Format
Structure
type(scope): Imperative description
[Body explaining what and why, not how]
Type System (Project-Specific)
content- Adding/updating chapters, sections in Typst filesexample- Adding/modifying Rust code examplesfix- Correcting errors, typos, broken code, incorrect output commentsrefactor- Restructuring code without changing functionalitystyle- Code formatting (cargo fmt), Typst formatting (typstyle)build- Changes to justfile, Cargo.toml, or build configurationdocs- Updates to README.md, CLAUDE.md, or other documentationchore- Maintenance tasks, dependencies, gitignore updates
Single Type Rule: Each commit MUST have exactly one type. If changes span multiple types (e.g., both content and examples), create separate commits for each type.
Scope Guidelines
Part X- Changes to a specific partPart X, Chapter Y- Changes to specific chapterAll Parts- Changes across multiple parts- Omit scope for project-wide changes (build, docs, chore)
Subject Line Rules
- Imperative mood - "Add feature" not "Added feature" or "Adds feature"
- Lowercase after colon -
fix: correct typonotfix: Correct typo - No period at end -
docs: update READMEnotdocs: update README. - Under 72 characters (soft limit) - Be concise but clear
Body Rules
- Required for non-trivial changes - Simple fixes can omit the body
- Explain what and why - Not how (the diff shows how)
- Use bullet points for multiple changes
- Blank line between subject and body
- Wrap at 72 characters for readability - Use
fmt -w 72or editor settings to enforce - Format consistently - Each paragraph should be properly wrapped, not just the first line
Commit Message Examples
Example 1: Single Type with Scope
content(Part 1): Add section on ownership and borrowing
Introduces ownership concepts with Java comparisons for easier
understanding by the target audience. Includes memory diagrams
showing heap vs stack allocation.
Example 2: Multiple Files, Single Type
example(Part 3): Add more code examples for Part 3
Added 2 practical examples:
- format_precision.rs - Floating point precision
- format_width.rs - Field width control
All examples include output comments verified by running the code.
Example 3: Fix with Detailed Body
fix(Part 4): Correct Display trait output comments
The output comments were showing incorrect values due to
outdated code. Updated after running:
cargo run --bin point_display
cargo run --bin temperature
Also fixed a typo in the chapter text explaining the trait.
Example 4: Simple Fix (No Body Needed)
fix(Part 2): Correct typo in println macro explanation
Example 5: Project-Wide Change
style: Format all Rust code and update justfile
- Applied cargo fmt to all code examples in Parts 1-5
Example 6: Documentation Only
docs: Enhance CLAUDE.md with quick reference section
Added essential commands cheat sheet and project structure
diagram for easier onboarding of AI agents and contributors.
Validation Before Committing
For Code Examples
# Validate the affected part
cd code/chap-XX/rust-examples
cargo build --all
# Or validate all parts
just validate
For Typst Changes
# Build the book to ensure it compiles
just build
Important Notes
- Several chapters contain intentional compilation errors for pedagogical purposes:
code/chap-01/rust-examples/src/placeholder_mismatch.rs- Placeholder count mismatchcode/chap-01/rust-examples/src/ownership_scope.rs- Ownership violationcode/chap-01/rust-examples/src/exclamation_mark.rs- Missing macro!code/chap-02/rust-examples/src/point_no_display.rs- Missing Display traitcode/chap-03/rust-examples/src/struct_no_debug.rs- Missing Debug traitcode/chap-03/rust-examples/src/tuple_no_display.rs- Tuples don't implement Displaycode/chap-04/rust-examples/src/point_no_display.rs- Missing Display trait- All code examples MUST include
// Output:or// Error:comments - Error comments in Chapters 3+ should only show primary error line and location
- Always run code to verify output comments before committing
Commit Workflow Patterns
Pattern 1: Content + Examples (Separate Commits)
When adding a new section with accompanying code examples, commit them separately:
# First commit - Content
git add formats/typst/en_US/parts/part-02/chap-01.typ
git commit -m "$(cat <<'EOF'
content(Part 2): Add section on print vs println macros
Explains the difference between print! and println! macros,
their buffering behavior, and when to use each variant.
Includes Java comparisons for familiar reference points.
EOF
)"
# Second commit - Examples
git add code/chap-02/rust-examples/src/print_example.rs
git add code/chap-02/rust-examples/Cargo.toml
git commit -m "$(cat <<'EOF'
example(Part 2): Add print/println demonstration code
Implements practical examples showing:
- Basic print! vs println! usage
- Buffering behavior differences
- Flushing stdout manually
EOF
)"
Pattern 2: Separate Unrelated Changes
When changes span different concerns:
# First commit - Content changes
git add formats/typst/en_US/parts/part-02/*.typ
git commit -m "$(cat <<'EOF'
content(Part 2): Expand explanation of format strings
Added subsection explaining positional vs named arguments
with comparison to Java's String.format().
EOF
)"
# Second commit - Code examples
git add code/chap-02/rust-examples/src/*.rs
git add code/chap-02/rust-examples/Cargo.toml
git commit -m "$(cat <<'EOF'
example(Part 2): Add format argument demonstrations
Added three examples showing different argument styles:
- positional_args.rs - Positional arguments
- named_args.rs - Named arguments
- mixed_args.rs - Combining both styles
EOF
)"
# Third commit - Fixes
git add code/chap-03/rust-examples/src/debug_trait.rs
git commit -m "fix(Part 3): Update Debug trait output comment"
Pattern 3: Style Changes (Keep Separate)
Always separate formatting from content:
# Format first
just format
git add -u
git commit -m "style: Apply cargo fmt to all code examples"
# Then commit actual changes
git add <files>
git commit -m "content(Part X): ..."
Pattern 4: Using Selective Hunk Staging
When a file has unrelated changes in different hunks:
Identifying Hunks
First, examine the diff to identify which hunks contain which changes:
# View the diff with hunk headers
git diff HEAD -- CLAUDE.md
# Count the hunks (lines starting with @@)
git diff HEAD -- CLAUDE.md | grep -c "^@@"
# Examine each hunk to determine what it changes
# Hunks are numbered sequentially from 1
Staging Specific Hunks
# Check if filterdiff is available
command -v filterdiff
# Generate diff
git diff HEAD -- CLAUDE.md > /tmp/claude.diff
# Stage only documentation hunks (e.g., hunks 1,2,4)
filterdiff --hunks=1,2,4 /tmp/claude.diff > /tmp/selected.diff
git apply --cached /tmp/selected.diff
git commit -m "docs: Add slash commands documentation"
# Stage remaining hunks for separate commit
git add CLAUDE.md
git commit -m "docs: Update hard rules section"
Tip: If filterdiff is not available, use git add -p CLAUDE.md for interactive staging.
Special Commit Scenarios
Amending Commits
Only amend commits that haven't been pushed to a remote repository:
# Check if the last commit has been pushed
git status # Look for "Your branch is ahead of 'origin/branch' by 1 commit"
# Amend to add forgotten files (keeps same message)
git add <forgotten-file>
git commit --amend --no-edit
# Amend to fix the commit message
git commit --amend -m "$(cat <<'EOF'
fix(Part 2): Correct ownership example
Fixed the borrowing demonstration to properly show
move semantics vs borrowing.
EOF
)"
# Amend to add changes AND update message
git add <files>
git commit --amend
WARNING: Never amend commits that have been pushed unless you're prepared to force-push and potentially disrupt other contributors.
Handling Merge Commits
Generally avoid merge commits by rebasing feature branches. When necessary:
# For feature branch merges
git merge --no-ff feature-branch -m "$(cat <<'EOF'
Merge 'feature-branch': Add comprehensive error handling
Integrates new error handling system across all chapters
with improved pedagogical examples showing common pitfalls.
EOF
)"
Work-in-Progress (WIP) Commits
For incomplete work that needs to be saved:
# Create a WIP commit (to be amended later)
git add .
git commit -m "WIP: [description of partial work]"
# Later, when work is complete, amend with proper message
git add <remaining-changes>
git commit --amend -m "$(cat <<'EOF'
content(Part 3): Add section on trait bounds
Explains trait bounds with Java generics comparisons
and practical examples of common constraints.
EOF
)"
Decision Tree
- Check current state:
- Run
git statusto see uncommitted changes - Run
git diff --stagedto review staged changes - Run
git log -1to check if you need to amend
- Analyze changes:
- Modified
.typfiles → Content change - Modified
.rsfiles → Example change - Modified
Cargo.tomlorjustfile→ Build change - Modified
.mdfiles → Documentation change
- Determine relationship:
- All changes same type → Single commit
- Changes span multiple types → Separate commits (one per type)
- Unrelated changes → Multiple commits
- Mixed hunks in one file → Use
filterdifforgit add -p
- Determine scope:
- Single part affected → Use
(Part X)scope - Multiple parts → Use
(All Parts)or omit scope - Project-wide → Omit scope
- Write commit message:
- Simple change → Subject line only
- Complex change → Subject + detailed body
- Use imperative mood, lowercase after colon
- Keep subject under 72 characters
- Wrap body text at 72 characters using
fmtor editor settings
- Validate before committing:
- Code changes → Run
just validate - Typst changes → Run
just build - Check output comments are accurate by running the code
Validation Checklist
- [ ] Code examples compile (except intentional errors)
- [ ] Output comments match actual output (run the code!)
- [ ] Typst book builds successfully (
just build) - [ ] Commit message follows format rules
- [ ] Subject line under 72 characters
- [ ] Uses imperative mood
- [ ] Includes scope when applicable
- [ ] Body included for non-trivial changes
- [ ] All modified files staged in at least one commit
- [ ] No unrelated changes staged together
Commit Message Guidelines
Soft Guidelines
- Keep the first line under 72 characters when possible
- Prefer smaller, atomic commits over large monolithic ones
- When in doubt, add a body explaining the change
- Use descriptive branch names that reflect the changes
Hard Requirements
The following are absolute requirements from .claude/hard-rules.md:
- Single Type: Each commit MUST have exactly one type - never combine types
- Staging: Every file must be part of at least one commit
- Focus: Only stage related changes together (atomic commits)
- Bodies: Non-trivial changes require explanatory body text
- Validation: Always validate before committing (
just validatefor code,just buildfor content) - Types: Use only project-specific types (
content,example,fix, etc. - neverfeat)
Quick Reference: Common Scenarios
| Scenario | Type | Scope | Example |
| ---------------------- | --------- | ---------- | ------------------------------------------ |
| Add chapter section | content | (Part X) | content(Part 1): Add ownership section |
| Add code example | example | (Part X) | example(Part 2): Add println demo |
| Add content + code: | | | |
| → First commit | content | (Part X) | content(Part 3): Add Debug trait section |
| → Second commit | example | (Part X) | example(Part 3): Add Debug trait demos |
| Fix typo | fix | (Part X) | fix(Part 1): Correct variable name |
| Fix output comment | fix | (Part X) | fix(Part 4): Update Display output |
| Run cargo fmt | style | Omit | style: Apply cargo fmt to all examples |
| Update justfile | build | Omit | build: Add format-check command |
| Update CLAUDE.md | docs | Omit | docs: Add commit conventions |
| Update .gitignore | chore | Omit | chore: Add build artifacts to gitignore |
Tips for Success
- Read recent commits - Use
git log --oneline -20to follow established patterns - One type per commit - Never combine types; split content and examples into separate commits
- Think atomically - One logical change per commit (can span multiple files if same type)
- Explain why, not what - The diff shows what changed, the body explains why it was necessary
- Verify everything - Run the code, build the book, check for errors before committing
- Use descriptive scopes - Help readers quickly identify affected areas
- Keep it focused - If you're listing more than 3-4 things in the body, consider splitting commits
- Review staged changes - Always use
git diff --stagedas final check before commit - Use TodoWrite for complexity - Track multi-commit workflows with todo items
- Format consistently - Use heredocs for multi-line messages, wrap body at 72 chars
- Test intentional errors - Verify that pedagogical error examples still produce expected errors
~~~
Claude Model
Sonnet (default)
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.0.22
Platform
Anthropic API
Operating System
Other Linux
Terminal/Shell
Other
Additional Information
Add Ghostty to the list of terminals, as it is becoming increasingly popular.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗