fj cannot set issue labels or assignees, though issue edit --help says it can #95

Closed
opened 2026-06-10 21:20:08 +00:00 by stephen · 2 comments
Owner

Observation

There is no way to set an issue's labels or assignees from fj, even though the CLI advertises it.

  • fj issue create exposes no --label/--assignee flags, and the handler hardcodes both to None (src/cli/issue.rs:309-314):
    let payload = CreateIssue {
        title: &title,
        body: body.as_deref(),
        assignees: None,
        labels: None,
    };
    
  • fj issue edit exposes no --label/--assignee flags either, and the patch it sends carries only title/body/state (src/cli/issue.rs:333-337):
    let patch = EditIssue {
        title: args.title.as_deref(),
        body: body.as_deref(),
        state: None,
    };
    
  • Yet the Edit command's doc-comment and --help text both claim otherwise (src/cli/issue.rs:27): "Edit an issue's title, body, labels, or assignees." fj issue edit --help prints "Edit an issue's title, body, labels, or assignees" while offering only --title and --body.

The only --label/--assignee flags that exist are read-side filters on fj issue list (src/cli/issue.rs:79-84), not write operations. The underlying API layer already models the fields (CreateIssue.labels, CreateIssue.assignees, and EditIssue could carry them), so the gap is purely at the CLI surface.

Practical proof: filing this very batch of issues, applying a label required falling back to fj api because fj issue create/edit cannot do it.

Why it matters

Labeling and assigning are the core of issue triage, the daily loop for any dev team on the forge. gh issue create --label/--assignee and gh issue edit --add-label/--add-assignee are table stakes, and fj markets "full feature parity with gh for the surface Forgejo exposes." A team scripting triage (or an AI agent doing it) discovers, after the help text told them it works, that fj can open and close issues but can't route or categorize them. The lying help text is worse than a missing feature: it costs a debugging session before the user concludes the capability isn't there.

Possible directions (sketches)

  • (sketch) Add --label/--assignee (repeatable, comma-split) to fj issue create, threading into the already-present CreateIssue.labels/assignees. Forgejo's create endpoint takes label IDs, so resolve names → IDs via the labels API first (mirror whatever fj label already does).
  • (sketch) Add --add-label/--remove-label/--add-assignee/--remove-assignee to fj issue edit, backed by the dedicated POST/DELETE /issues/{n}/labels and /assignees endpoints (gh-style additive semantics).
  • (sketch) Until the flags land, correct the issue edit doc-comment/help at issue.rs:27 so it stops promising labels/assignees it can't set.

Confidence

High. Verified end to end: no write-side flags in CreateArgs/EditArgs, both payloads drop the fields (issue.rs:309-337), the only label/assignee flags are list filters (issue.rs:79-84), and the help text claims the capability. Reproduced firsthand (had to use fj api to label issues in this repo).

## Observation There is no way to set an issue's labels or assignees from `fj`, even though the CLI advertises it. - `fj issue create` exposes no `--label`/`--assignee` flags, and the handler hardcodes both to `None` (`src/cli/issue.rs:309-314`): ```rust let payload = CreateIssue { title: &title, body: body.as_deref(), assignees: None, labels: None, }; ``` - `fj issue edit` exposes no `--label`/`--assignee` flags either, and the patch it sends carries only title/body/state (`src/cli/issue.rs:333-337`): ```rust let patch = EditIssue { title: args.title.as_deref(), body: body.as_deref(), state: None, }; ``` - Yet the `Edit` command's doc-comment and `--help` text both claim otherwise (`src/cli/issue.rs:27`): "Edit an issue's title, body, **labels, or assignees**." `fj issue edit --help` prints "Edit an issue's title, body, labels, or assignees" while offering only `--title` and `--body`. The only `--label`/`--assignee` flags that exist are read-side **filters** on `fj issue list` (`src/cli/issue.rs:79-84`), not write operations. The underlying API layer already models the fields (`CreateIssue.labels`, `CreateIssue.assignees`, and `EditIssue` could carry them), so the gap is purely at the CLI surface. Practical proof: filing this very batch of issues, applying a label required falling back to `fj api` because `fj issue create`/`edit` cannot do it. ## Why it matters Labeling and assigning are the core of issue triage, the daily loop for any dev team on the forge. `gh issue create --label/--assignee` and `gh issue edit --add-label/--add-assignee` are table stakes, and `fj` markets "full feature parity with gh for the surface Forgejo exposes." A team scripting triage (or an AI agent doing it) discovers, after the help text told them it works, that `fj` can open and close issues but can't route or categorize them. The lying help text is worse than a missing feature: it costs a debugging session before the user concludes the capability isn't there. ## Possible directions (sketches) - *(sketch)* Add `--label`/`--assignee` (repeatable, comma-split) to `fj issue create`, threading into the already-present `CreateIssue.labels`/`assignees`. Forgejo's create endpoint takes label **IDs**, so resolve names → IDs via the labels API first (mirror whatever `fj label` already does). - *(sketch)* Add `--add-label`/`--remove-label`/`--add-assignee`/`--remove-assignee` to `fj issue edit`, backed by the dedicated `POST/DELETE /issues/{n}/labels` and `/assignees` endpoints (gh-style additive semantics). - *(sketch)* Until the flags land, correct the `issue edit` doc-comment/help at `issue.rs:27` so it stops promising labels/assignees it can't set. ## Confidence High. Verified end to end: no write-side flags in `CreateArgs`/`EditArgs`, both payloads drop the fields (`issue.rs:309-337`), the only label/assignee flags are list filters (`issue.rs:79-84`), and the help text claims the capability. Reproduced firsthand (had to use `fj api` to label issues in this repo).
Author
Owner

Converted (label converted). Split into two backlog items along the create vs edit surfaces:

  • rasterstate/fj#97 (backlog, p1): Add --label/--assignee to fj issue create (resolve label names to IDs, thread into the already-modeled CreateIssue.labels/assignees).
  • rasterstate/fj#98 (backlog, p2): Add --add-label/--remove-label/--add-assignee/--remove-assignee to fj issue edit, backed by the dedicated labels/assignees endpoints, and fix the lying doc-comment at src/cli/issue.rs:27.

Kept open per the product-agent triage convention. Rationale: this is a verified gh-parity gap in the core triage loop plus a help text that actively claims a capability it lacks, and it was hit firsthand filing this very batch (labels had to be applied through fj api .../issues/<n>/labels). Create-side is p1 because it unblocks scripted/agent triage filing (the exact pain in this pass); edit-side add/remove is p2 as the follow-on relabel/reassign loop and carries the help-text correction. The help-text-only stopgap from the sketch was not filed separately: both items make the help accurate as part of their acceptance, so a standalone doc fix would be make-work.

**Converted** (label `converted`). Split into two backlog items along the create vs edit surfaces: - rasterstate/fj#97 (`backlog`, `p1`): Add `--label`/`--assignee` to `fj issue create` (resolve label names to IDs, thread into the already-modeled `CreateIssue.labels`/`assignees`). - rasterstate/fj#98 (`backlog`, `p2`): Add `--add-label`/`--remove-label`/`--add-assignee`/`--remove-assignee` to `fj issue edit`, backed by the dedicated labels/assignees endpoints, and fix the lying doc-comment at `src/cli/issue.rs:27`. Kept open per the product-agent triage convention. Rationale: this is a verified `gh`-parity gap in the core triage loop plus a help text that actively claims a capability it lacks, and it was hit firsthand filing this very batch (labels had to be applied through `fj api .../issues/<n>/labels`). Create-side is p1 because it unblocks scripted/agent triage filing (the exact pain in this pass); edit-side add/remove is p2 as the follow-on relabel/reassign loop and carries the help-text correction. The help-text-only stopgap from the sketch was not filed separately: both items make the help accurate as part of their acceptance, so a standalone doc fix would be make-work.
Author
Owner

All derived backlog items merged: rasterstate/fj#97 (PR #101) and rasterstate/fj#98 (PR #104). Closing this opportunity per the issue state machine.

All derived backlog items merged: rasterstate/fj#97 (PR #101) and rasterstate/fj#98 (PR #104). Closing this opportunity per the issue state machine.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
rasterstate/fj#95
No description provided.