Skip to content

Issues

The issues command (alias i) manages Redmine issues end-to-end.

Terminal window
redmine issues list [flags]
Flag Description
--project Filter by project (name, identifier, or ID)
--tracker Filter by tracker (name or ID)
--status Filter by status: open, closed, *, name, or ID
--assignee Filter by assignee: me, none (unassigned), user or group name, login, or ID. See assignee resolution
--author Filter by author: me, name, login, or ID. An unresolvable name is an error, see assignee resolution
--priority Filter by priority (name or ID)
--category Filter by issue category (name or ID)
--version Filter by target version (name or ID)
--parent Restrict to children of a parent issue ID
--subproject Subproject filter: numeric ID, or !* to exclude subprojects
--include-subprojects Include issues from subprojects (default true; pair with =false to exclude)
--is-private Filter by privacy: true returns private issues only, false public only
--filter Raw Redmine filter as key=value (repeatable). Use for date ranges, custom fields, subject text
--query Run a saved query by name (see queries)
--query-id Run a saved query by numeric ID (mutually exclusive with --query)
--sort Sort order, e.g. updated_on:desc
--include Include related data: attachments, relations
--attachments Shorthand for --include attachments
--relations Shorthand for --include relations
--limit Maximum number of results (0 for all)
--offset Result offset for pagination
-o, --output Output format: table, json
Terminal window
redmine issues list --assignee me
Terminal window
redmine issues get <id> [flags]

Aliases: show, view.

Flag Description
--include Include related data: journals, children, relations, attachments
--journals Shorthand for --include journals
--children Shorthand for --include children
--relations Shorthand for --include relations
--attachments List the issue’s attachments (id, filename, size, content type)
--download-attachments Download every attachment of the issue into the given directory
--clobber With --download-attachments, overwrite files that already exist in the directory
--allow-hidden With --download-attachments, allow saving attachments whose filename starts with .
-o, --output Output format

--download-attachments never overwrites a file that already exists in the directory unless you pass --clobber, and refuses server-supplied names starting with . (such as .bashrc or .envrc) unless you pass --allow-hidden. Every destination is checked before anything is downloaded, so a conflict aborts the command without writing any file. The same rules as attachments download apply: symlinks are never followed, directories are never replaced, and a failed download leaves no partial file.

Attachments of the same issue often share a filename (for example several screenshot.png). They are all kept: the newest (the one with the highest attachment ID, usually a corrected re-upload) keeps its name and older ones get their attachment ID added, such as screenshot (attachment-71).png. Names that differ only in case are treated as the same name on every platform, because macOS and Windows filesystems usually cannot hold both. Each confirmation on stderr shows the path the attachment was saved to. This renaming only covers names within one download; --clobber covers files that were already there.

Terminal window
# List attachment IDs so you can download one
redmine issues get 123 --attachments
Terminal window
redmine issues create [flags]
Flag Description
--project Project (name, identifier, or ID) — falls back to the default project of the active profile
--subject Issue subject — required
--tracker Tracker (name or ID)
--status Status (name or ID)
--priority Priority (name or ID)
--assignee Assignee: me, user or group name, login, or ID. none clears the assignee on update; on create it sets no assignee, though Redmine may still apply the category or project default assignee. See assignee resolution
--description Issue description
--description-file Read the description from a file (- reads standard input); mutually exclusive with --description; an empty or whitespace-only file is rejected
--parent Parent issue ID
--category Category (name or ID)
--version Target version (name or ID)
--start-date Start date (YYYY-MM-DD)
--due-date Due date (YYYY-MM-DD)
--estimated-hours Estimated hours
--private Mark as private
--watcher Initial watcher (name, login, ID, or me; repeatable)
--custom-field Custom field value as name=value or id=value (repeatable)
--attach File path to attach (repeatable)
Terminal window
redmine issues create --project myproject --subject "Add search" --tracker Feature --priority High
redmine issues create --project myproject --subject "Bug report" \
--start-date 2026-05-01 --due-date 2026-05-15 \
--watcher me --watcher "QA Bot" \
--custom-field Severity=High \
--attach /path/to/screenshot.png --attach /path/to/log.txt
# Values with spaces: quote the whole pair and repeat the flag per field
redmine issues create --project myproject --subject "Bug" \
--custom-field "2=Value for field 2" \
--custom-field "61=Value for 61"
# Child issue under an epic, with a category
redmine issues create --project myproject --parent 1234 --tracker Task \
--category "Backend" --subject "Implement API endpoint"
# Attach a screenshot and embed it inline in a Textile description (!filename!);
# on servers using Markdown/CommonMark formatting write ![](screenshot.png) instead
redmine issues create --project myproject --subject "Broken layout" \
--attach ./screenshot.png --description 'Layout breaks on resize: !screenshot.png!'
# Long Textile/Markdown description from a file, no shell quoting needed
redmine issues create --project myproject --subject "Spec" --description-file spec.textile

If Redmine starts the new issue in a different status than --status asked for (its workflow does not allow new issues of that tracker to start there for your role), the command prints a warning on stderr. It still exits 0, because the issue was created and a retry would duplicate it.

Terminal window
redmine issues update <id> [flags]

Accepts the same flags as create (except --project and --watcher) plus:

Flag Description
--note Add a journal note
--note-file Read the journal note from a file (- reads standard input); mutually exclusive with --note; an empty or whitespace-only file is rejected
--description-file Read the new description from a file (- reads standard input); mutually exclusive with --description; an empty or whitespace-only file is rejected (pass --description "" to clear the description)
--private-notes Mark the journal note from --note / --note-file as private
--done-ratio Completion percentage (0-100)
--start-date Start date (empty string clears)
--due-date Due date (empty string clears)
--custom-field Custom field value as name=value or id=value (repeatable)
--attach File path to attach (repeatable)
Terminal window
redmine issues update 123 --note "Fixed the bug" --attach /path/to/fixed_code.patch
# Private journal note visible only to staff
redmine issues update 123 --note "Internal context" --private-notes
# Update custom field by name
redmine issues update 123 --custom-field Severity=Critical
# Assign to a group by name, or clear the assignee
redmine issues update 123 --assignee "Backend Team"
redmine issues update 123 --assignee none
# Long description from a file, note piped in on stdin
redmine issues update 123 --description-file description.textile
generate-report | redmine issues update 123 --note-file -

Redmine answers an issue update with success even when it silently ignores the requested status: transitions its workflow does not allow for your role and the issue’s tracker are dropped, and so is closing an issue that still has open subtasks or is blocked by an open issue. So whenever a status change is requested (update --status, close, reopen), the CLI reads the issue back. If the status did not change, the command fails like any other error, with exit status 1:

  • the message explains what happened and names the current status,
  • the details list the statuses you can move the issue to (Redmine 5.0+; older servers cannot report them) and, when the request carried more than the status, warn that those other changes (fields, notes, attachments) may already have been applied, so do not resend them blindly,
  • with -o json, this is the standard error envelope with code status_not_applied.

close and reopen only care about open versus closed: closing an issue that is already in another closed status (say Rejected) succeeds with a note on stderr instead of failing. Updates without a status change do not trigger the extra request.

In JSON mode stdout stays empty and the envelope is a single line, the last line of stderr:

Terminal window
$ redmine issues close 123 -o json 2>err.log
$ echo $?
1
$ tail -n1 err.log
{"error":{"message":"Issue #123: status was not changed to \"Closed\" (ID 5); it is now \"New\" (ID 1). Redmine silently ignores status transitions that its workflow does not allow for your role and the issue's tracker, and refuses to close issues that have open subtasks or are blocked by open issues.","code":"status_not_applied","details":["Allowed statuses: New (1), In Progress (2), Resolved (3), Feedback (4)."]}}

On success the action envelope is unchanged; to see the issue after an update, run redmine issues get <id>.

Terminal window
redmine issues close <id> [flags]
Flag Description
--note Add a closing comment
--note-file Read the closing comment from a file (- reads standard input); an empty or whitespace-only file is rejected

Sets the first closed status. The result is verified.

Terminal window
redmine issues reopen <id> [flags]
Flag Description
--note Add a comment when reopening
--note-file Read the comment from a file (- reads standard input); an empty or whitespace-only file is rejected

Sets the first open status. The result is verified.

Terminal window
redmine issues assign <id> <assignee> [flags]

The assignee argument accepts a numeric ID, me, a user or group name, a login, or none to clear the assignee.

Terminal window
redmine issues assign 123 me
redmine issues assign 123 "Backend Team" # a group that is a project member
redmine issues assign 123 none # unassign

--assignee (and the assign / watchers user argument) resolves names like this:

  1. Numeric IDs, me, and none are used directly, with no name lookup.
  2. With project context, names are matched (case-insensitively) against the project’s members, users and groups alike. The context is --project (or the default project) for list and create, and the issue’s own project for update, assign, and watchers. Project memberships are readable by any project member, so this works without admin rights.
  3. The users list, which Redmine only exposes to administrators, is checked when the input could be a login (no spaces), when several members share the name, or when no member matched. An exact login match wins over display names, so --assignee max picks the user whose login is max even if another member is displayed as “Max”. Without admin rights the membership match stands.

When nothing matches, the error lists the project’s members (marked [user] or [group]) so you can pick the right name or ID. When two members share a name and no login settles it, the CLI asks for the numeric ID instead of picking one.

Terminal window
redmine issues comment <id> --message "Your comment" [flags]
Flag Description
-m, --message Comment text
-F, --message-file Read the comment from a file (- reads standard input); mutually exclusive with --message; an empty or whitespace-only file is rejected
Terminal window
redmine issues comment 123 --message-file notes.textile
git log -1 --format=%B | redmine issues comment 123 -F -

File contents are sent as read (UTF-8, no trimming; only a leading byte-order mark is dropped), so multi-line Textile or Markdown needs no shell quoting.

Terminal window
redmine issues watchers list <id>
redmine issues watchers add <id> <user>
redmine issues watchers remove <id> <user>

<user> accepts a numeric ID, login, full name, or me. Names are matched against the issue’s project members first (see assignee resolution).

Terminal window
redmine issues watchers add 123 me
redmine issues watchers list 123
redmine issues watchers remove 123 alice
Terminal window
redmine issues relations list <id>
redmine issues relations add <id> --to <other-id> --type <type> [--delay <days>]
redmine issues relations remove <relation-id>
Flag Description
--to Target issue ID — required
--type Relation type. Default relates. See table below
--delay Number of days delay. Only valid for precedes/follows

Supported relation types (from the Redmine REST docs):

Type Meaning
relates Generic association
duplicates This issue duplicates the target
duplicated This issue is duplicated by the target
blocks This issue blocks the target
blocked This issue is blocked by the target
precedes This issue precedes the target (accepts --delay)
follows This issue follows the target (accepts --delay)
copied_to This issue was copied to the target
copied_from This issue was copied from the target
Terminal window
redmine issues relations add 123 --to 124 --type blocks
redmine issues relations add 123 --to 124 --type precedes --delay 5
redmine issues relations list 123
redmine issues relations remove 42
destructive
Terminal window
redmine issues delete <id> [flags]
Flag Description
-f, --force Skip confirmation prompt
Terminal window
redmine issues open <id>

Constructs the issue URL from your configured Redmine server and opens it in your default browser.

Terminal window
redmine issues open 123 # → https://redmine.example.com/issues/123

The URL must be an absolute http or https URL; anything else is refused. The browser is launched with open (macOS), xdg-open (Linux and BSD) or rundll32 url.dll,FileProtocolHandler (Windows), never through a shell.

Terminal window
redmine issues browse [flags]

Opens an interactive terminal browser for issues. Accepts the same filter flags as list.