DocsIssue PropertiesRelationships
Back
Issue Properties

Relationships

xpo link <source> <target> -t blocks

Relationship types

KindInverseMeaning
blocksblocked_bySource blocks target from starting
depends_ondependency_ofSource depends on target being done
duplicatesduplicated_bySource duplicates target
relates_torelates_toSymmetric, informational

Types are case-insensitive, and blocked-by or BlockedBy work as well as blocked_by.

A link is stored once, on the issue you created it from, and read from both sides: A blocks B also means B blocked_by A. Showing B lists the inverse as a derived link, so you never need to create both directions.

Two issues can have at most one link between them. Linking a pair that's already linked fails and names the existing link:

Error linking issues: myapp-a1b2c3 is already linked to myapp-b2c3d4 (blocks); set overwrite to replace it with relates_to

To change the kind, pass --overwrite. It replaces the existing link, whichever issue stores it, and says what it replaced:

xpo link myapp-a1b2c3 myapp-b2c3d4 -t relates_to --overwrite
# Linked myapp-a1b2c3 relates_to myapp-b2c3d4 (replaced blocks)

In JSON and MCP, set "overwrite": true; the result lists what was replaced under replaced. Creating the exact same link again also fails (already exists). add and update reject a links set with two entries for the same issue. Pairs that were linked more than once before xpo 1.4.0 keep working until a write changes them.

In xpo show --json and the MCP show tool, links appear under dependencies, and inverse links stored on the other issue carry "derived": true:

"dependencies": [
  {"source_id": "myapp-b2c3d4", "target_id": "myapp-a1b2c3", "kind": "blocked_by", "derived": true}
]
xpo unlink <source> <target> -t blocks

unlink removes one relationship, whichever side stores it — xpo unlink B A -t blocked_by also removes A blocks B stored on A. Links to deleted issues can be removed by the deleted issue's ID.

Enforcement

Only blocked_by gates work: an issue can't move to DOING until every blocker, stored on either side, is DONE. CANCELED and DUPLICATE blockers still block until you remove the link or point it at another issue. If you try to xpo start a blocked issue, xpo tells you which issue is blocking it and to remove the link. On the board, Start Work is disabled, and its tooltip lists the blockers with a Remove link button for canceled and duplicate ones. All other kinds are informational. See Status for the full issue lifecycle.

From the board

In an issue's sidebar, the Relationships button (flag icon) shows how many relations the issue has — "No relations", "1 Relationship", "3 Relationships" — counting its parent as one. Click it to add a relation:

  • Remove parent — first in the menu, when the issue has a parent
  • Parent of…, Sub-issue of… — set this issue as the parent of another, or pick its parent
  • Related to…, Blocked by…, Blocking…, Duplicate of…
  • More — Depends on…, Dependency of…, Duplicated by…

Picking a kind opens an issue search. Sub-issue of… only offers open, top-level issues outside this issue's own subtree.

The Relations card lists the links in sections worded from the issue you're viewing — Related, Blocked by, Blocking, Depends on, Dependency of, Duplicate of, Duplicated by. Each linked issue is a chip:

  • Click opens the issue; hover for a moment to preview its ID, assignee, title, status, and priority.
  • × (on hover) removes the relation.
  • Right-click offers Change to (switch the link's kind in place), Remove relation, and Copy link (the linked issue's URL).

The waypoints button in the card's corner opens the issue in the dependency graph.

View dependencies

xpo show <id>

Dependencies are listed in the issue's detail view, including inverse links stored on the other issue. The web board also has a dedicated Dependencies view that visualizes the full graph of blocking relationships across all issues.

Add links at creation time:

xpo add --json <<'EOF'
{
  "title": "Subtask",
  "links": [{"target": "myapp-a1b2c3", "type": "blocked_by"}]
}
EOF

When updating, links is the issue's full relationship set, including derived links (as returned by show). A link you leave out is removed from whichever side stores it, and "links": [] removes them all. Omit links to leave them unchanged.

echo '{"links": []}' | xpo update <id> --json