Sub-Issues
Sub-issues allow you to break down larger work items into smaller, manageable pieces while maintaining hierarchical relationships. This guide covers how to create, manage, and query sub-issue relationships.
Understanding Sub-Issue Relationships
Sub-issues create parent-child relationships between issues, allowing you to:
- Break down Epics into Stories
- Divide Stories into Tasks
- Create multi-level work hierarchies
- Track progress at different levels
Important Constraints
- GitHub issues can have parents that are either GitHub or Zenhub issues
- Zenhub issues can only have Zenhub issues as parents
- Sub-issues inherit workspace context from their parent issue
- You can create unlimited levels of hierarchy
Creating Sub-Issues
Option 1: Create a New Sub-Issue
Create a new issue as a child of an existing issue:
mutation createSubIssue($CreateIssueInput: CreateIssueInput!) {
createIssue(input: $CreateIssueInput) {
issue {
id
title
parentIssue {
id
title
}
}
}
}
Variables:
{
"CreateIssueInput": {
"title": "Implement user authentication",
"body": "Sub-task for the main Epic",
"repositoryId": "REPOSITORY_ID",
"parentIssueId": "PARENT_ISSUE_ID"
}
}
Option 2: Add Existing Issues as Sub-Issues
Convert existing issues into sub-issues of a parent:
mutation addSubIssues($childIssueIds: [ID!]!, $parentIssueId: ID!) {
addSubIssues(input: {
childIssueIds: $childIssueIds,
parentId: $parentIssueId
}) {
failedIssues {
id
title
}
successCount
}
}
Variables:
{
"childIssueIds": ["CHILD_ISSUE_ID_1", "CHILD_ISSUE_ID_2"],
"parentIssueId": "PARENT_ISSUE_ID"
}
Creating Multi-Level Hierarchies
Example: Initiative → Epic → Story → Task
- Create an Initiative (Level 1):
{
"CreateIssueInput": {
"title": "Q1 Platform Improvements",
"body": "High-level initiative for platform work",
"repositoryId": "ZENHUB_REPOSITORY_ID",
"issueTypeId": "INITIATIVE_ISSUE_TYPE_ID"
}
}
- Create Epics (Level 2) under the Initiative:
{
"CreateIssueInput": {
"title": "User Authentication Epic",
"body": "Improve user authentication flow",
"repositoryId": "ZENHUB_REPOSITORY_ID",
"issueTypeId": "EPIC_ISSUE_TYPE_ID",
"parentIssueId": "INITIATIVE_ID"
}
}
- Create Stories (Level 3) under Epics:
{
"CreateIssueInput": {
"title": "Implement 2FA",
"body": "Add two-factor authentication",
"repositoryId": "GITHUB_REPOSITORY_ID",
"issueTypeId": "STORY_ISSUE_TYPE_ID",
"parentIssueId": "EPIC_ID"
}
}
- Create Tasks (Level 4) under Stories:
{
"CreateIssueInput": {
"title": "Add SMS verification",
"body": "Implement SMS-based 2FA",
"repositoryId": "GITHUB_REPOSITORY_ID",
"issueTypeId": "TASK_ISSUE_TYPE_ID",
"parentIssueId": "STORY_ID"
}
}
Querying Sub-Issues
Get an Issue with Its Sub-Issues
query getIssueWithSubIssues($issueId: ID!, $workspaceId: ID!) {
node(id: $issueId) {
... on Issue {
id
title
childIssues(workspaceId: $workspaceId) {
nodes {
id
title
number
state
type
issueType {
... on ZenhubIssueType {
id
name
level
}
... on GithubIssueType {
id
name
level
}
}
repository {
id
name
}
}
totalCount
}
}
}
}
Get Sub-Issues with Pagination
For issues with many sub-issues, use pagination:
query getIssueWithSubIssuesPaginated(
$issueId: ID!,
$workspaceId: ID!,
$first: Int,
$after: String
) {
node(id: $issueId) {
... on Issue {
id
title
childIssues(workspaceId: $workspaceId, first: $first, after: $after) {
nodes {
id
title
state
}
pageInfo {
hasNextPage
endCursor
}
totalCount
}
}
}
}
Get an Issue with Its Parent
query getIssueWithParent($issueId: ID!) {
node(id: $issueId) {
... on Issue {
id
title
parentIssue {
id
title
number
issueType {
... on ZenhubIssueType {
id
name
level
}
... on GithubIssueType {
id
name
level
}
}
}
}
}
}
Get Complete Hierarchy
Get an issue with both its parent and children:
query getCompleteHierarchy($issueId: ID!, $workspaceId: ID!) {
node(id: $issueId) {
... on Issue {
id
title
number
issueType {
... on ZenhubIssueType {
id
name
level
}
... on GithubIssueType {
id
name
level
}
}
parentIssue {
id
title
number
issueType {
... on ZenhubIssueType {
name
level
}
... on GithubIssueType {
name
level
}
}
}
childIssues(workspaceId: $workspaceId) {
nodes {
id
title
number
state
issueType {
... on ZenhubIssueType {
name
level
}
... on GithubIssueType {
name
level
}
}
}
totalCount
}
}
}
}
Managing Sub-Issue Relationships
Remove Sub-Issue Relationships
While there's no direct "remove sub-issue" mutation, you can change the parent by creating a new relationship or setting a different parent.
Moving Sub-Issues Between Parents
To move a sub-issue to a different parent, use the addSubIssues
mutation with the new parent:
mutation moveSubIssue($childIssueIds: [ID!]!, $newParentIssueId: ID!) {
addSubIssues(input: {
childIssueIds: $childIssueIds,
parentId: $newParentIssueId
}) {
successCount
failedIssues {
id
title
}
}
}
Progress Tracking with Sub-Issues
Sub-Issue Summary Information
Many queries include dependency summary information that helps track progress:
dependenciesSummary {
childIssues {
totalCounts {
open
closed
inProgress
}
totalPoints {
open
closed
inProgress
}
}
}
This allows you to:
- Track how many sub-issues are completed
- See total story points across sub-issues
- Monitor progress across the hierarchy
Common Patterns
Epic → Story → Task Pattern
Initiative (Level 1)
├── Epic A (Level 2)
│ ├── Story 1 (Level 3)
│ │ ├── Task 1.1 (Level 4)
│ │ └── Task 1.2 (Level 4)
│ └── Story 2 (Level 3)
│ └── Task 2.1 (Level 4)
└── Epic B (Level 2)
└── Story 3 (Level 3)
Feature → Implementation Pattern
Feature Epic (Level 2)
├── Backend Implementation (Level 3)
│ ├── API Endpoint (Level 4)
│ └── Database Changes (Level 4)
├── Frontend Implementation (Level 3)
│ ├── UI Components (Level 4)
│ └── Integration (Level 4)
└── Testing (Level 3)
├── Unit Tests (Level 4)
└── E2E Tests (Level 4)
Related Guides
- Working with Issues - Basic issue CRUD operations
- Issue Types - Creating and managing issue types
- Getting Entity IDs - Finding required IDs
Best Practices
- Clear Hierarchy: Use consistent level patterns (Initiative → Epic → Story → Task)
- Meaningful Relationships: Only create sub-issues when there's a genuine parent-child relationship
- Repository Consistency: Keep related sub-issues in appropriate repositories (planning vs development)
- Progress Tracking: Use the dependency summaries to monitor completion across hierarchies
- Reasonable Depth: Avoid creating overly deep hierarchies that become hard to manage