# Github Issue Writing

> GitHub issue body and `[Type] Component:` title — bug/feature templates, repro steps, acceptance criteria. Use when filing a bug or feature request with gh.

- Skill: `laurigates/github-issue-writing` (Agent Skill)
- Install (CLI): `npx skillmds@latest add laurigates/github-issue-writing`
- Raw SKILL.md: https://api.skillmd.com/api/skills/laurigates/github-issue-writing/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: laurigates (https://skillmd.com/u/laurigates)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/laurigates/github-issue-writing

---


# GitHub Issue Writing

Create well-structured, actionable GitHub issues.

## When to Use This Skill

| Use this skill when... | Use the alternative when... |
|---|---|
| Filing a new bug, feature, or chore issue with clear title and acceptance criteria | Use `git-issue` to start working on existing issues end-to-end |
| Structuring an issue body with reproduction steps, scope, and definition of done | Use `github-issue-autodetect` to link existing issues from staged diffs |
| Choosing the `[Type] Component: Description` title format | Use `github-pr-title` to author the conventional title for the PR that fixes it |
| Designing a feature-request issue before implementation begins | Use `git-issue-manage` for transfer/pin/lock/develop-branch admin operations |
| Assembling the GitHub issue itself — title format, templates, `gh issue create` | Use `communication-plugin:ticket-drafting-guidelines` for the What/Why/How prose structure and house tone of the body text |

## Issue Title Format

```
[Type] Component: Brief description
```

| Type | Example |
|------|---------|
| Bug | `[Bug] Auth: Login fails with valid credentials` |
| Feature | `[Feature] API: Add rate limiting support` |
| Docs | `[Docs] README: Add installation instructions` |
| Chore | `[Chore] CI: Update Node.js version` |

**Guidelines:**
- Be specific (not "Bug" but "Login fails with OAuth")
- Include component for triage
- Keep under 72 characters

## Bug Report Template

```markdown
## Summary
Brief description of the bug.

## Steps to Reproduce
1. Go to '...'
2. Click on '...'
3. See error

## Expected Behavior
What should happen.

## Actual Behavior
What actually happens.

## Environment
- OS: macOS 14.0
- Browser: Chrome 120
- Version: 2.1.0
```

## Feature Request Template

```markdown
## Summary
What this feature does.

## Motivation
Why this is needed. What problem does it solve?

## Proposed Solution
Description of desired behavior.

## Acceptance Criteria
- [ ] Criterion 1
- [ ] Criterion 2
- [ ] Criterion 3
```

## Issue Types

GitHub supports first-class issue types. Use `--type` when creating issues:

| Type | Use For |
|------|---------|
| Bug | Something broken that needs fixing |
| Feature | New functionality request |
| Task | General work item |

Note: Available types depend on repository/org configuration. Use `gh issue create --type "Bug"` to leverage them.

## Body Content: Use `--body-file`

For any non-trivial body — anything containing backticks, code fences, or multi-line content — use `--body-file <path>`, never `--body "<text>"`. This applies to **all** `gh` commands that accept a body: `gh issue create`, `gh issue edit`, `gh issue comment`, `gh pr create`, `gh pr edit`, `gh pr comment`.

### When to use which

| Body shape | Pattern |
|---|---|
| Trivially short, single line, no backticks | `--body "Short text"` is fine |
| Contains backticks (inline code, code fences) | `--body-file /tmp/body.md` — required |
| Multi-line | `--body-file /tmp/body.md` — required |
| Contains shell metacharacters (`$`, `"`, `'`, `\`) | `--body-file /tmp/body.md` — required |

### Why

Shell-quoted `--body` strings escape backticks (`` ` `` becomes `` \` ``), breaking inline code spans and triple-backtick code fences in the rendered issue. Bash heredocs interact unpredictably with the agent's argument escaping. Writing the markdown to a file with the `Write` tool sidesteps shell quoting entirely — the file content is preserved byte-for-byte.

### Pattern

```
1. Write tool → /tmp/issue-body.md   (markdown body, no shell escaping)
2. gh issue create --title "..." --body-file /tmp/issue-body.md
```

The same `--body-file <path>` form is supported by every `gh` command that accepts a body.

## CLI Commands

```bash
# Create issue with a body file (preferred for any non-trivial body)
gh issue create --title "[Bug] Auth: Login fails" --body-file /tmp/issue-body.md

# Trivially short body — inline --body is acceptable
gh issue create --title "[Chore] Bump dep" --body "See renovate PR"

# With labels
gh issue create --title "..." --body-file /tmp/body.md --label "bug" --label "priority: high"

# With assignee
gh issue create --title "..." --body-file /tmp/body.md --assignee "@me"

# With issue type
gh issue create --title "..." --body-file /tmp/body.md --type "Bug"

# As sub-issue of a parent
gh issue create --title "..." --body-file /tmp/body.md
gh api repos/{owner}/{repo}/issues/{parent}/sub_issues -f sub_issue_id={new_id}

# Search before creating
gh issue list --search "login error" --state all
```

## Linking Issues

Pick the mechanism that matches the relationship — GitHub surfaces each one
differently and only the native APIs trigger "Blocked" badges on project boards.

| Relationship | How to record | Why |
|--------------|---------------|-----|
| Hard dependency (must happen before) | Native `dependencies/blocked_by` API — see `/git:issue-hierarchy --blocked-by N` | Sidebar "Relationships" entry + Blocked badge on boards |
| Composition (part-of scope) | Sub-issue API — see `/git:issue-hierarchy --add N` | Progress bar on parent, tracked separately from dependencies |
| Soft reference ("related to") | Plain markdown `Related to #789` in the body | Cross-link only; no lifecycle coupling |
| Auto-close on merge | `Fixes #N` / `Closes #N` footer in commit or PR body | Closes issue when the PR merges |

Do **not** write `Blocks #123` or `Blocked by #456` in issue bodies any more —
those strings used to be GitHub's workaround for missing dependency APIs, but
they are no longer parsed. Call `/git:issue-hierarchy` (or the REST endpoints
at `issues/{N}/dependencies/blocked_by`) so the relationship shows up in the
sidebar and on project boards.

## Quick Reference

| Action | Command |
|--------|---------|
| Create | `gh issue create --title "..." --body-file /tmp/body.md` |
| Create with type | `gh issue create --title "..." --body-file /tmp/body.md --type "Bug"` |
| Search | `gh issue list --search "keyword"` |
| View | `gh issue view N` |
| Edit body | `gh issue edit N --body-file /tmp/body.md` |
| Comment | `gh issue comment N --body-file /tmp/comment.md` |
| Labels | `gh label list` |

## Agentic Optimizations

| Context | Command |
|---------|---------|
| Create issue | `gh issue create --title "..." --body-file /tmp/body.md` |
| Create with type | `gh issue create --title "..." --type "Bug" --body-file /tmp/body.md` |
| List labels | `gh label list --json name` |
| Search issues | `gh issue list --search "keyword" --state all --json number,title` |
| View issue | `gh issue view N --json title,body,labels` |

