Skip to content

Fix incidents get/update/delete with sequential IDs (INC-xxx)#32

Merged
kwent merged 2 commits into
masterfrom
features/fix-issue-28
Jun 4, 2026
Merged

Fix incidents get/update/delete with sequential IDs (INC-xxx)#32
kwent merged 2 commits into
masterfrom
features/fix-issue-28

Conversation

@kwent
Copy link
Copy Markdown
Member

@kwent kwent commented Jun 4, 2026

Summary

  • rootly incidents get INC-31 was failing with "incident not found" because the CLI passed INC-31 verbatim to /v1/incidents/INC-31, but the API expects UUID, slug, or bare numeric sequential ID
  • Added NormalizeIncidentID() to strip the INC- prefix (case-insensitive), so INC-3131 before hitting the API
  • Applied normalization to get, update, and delete commands; user-facing messages still show the original INC-xxx format
  • Added unit tests for the normalizer and integration tests verifying the correct API path is called

Closes #28

Test plan

  • TestNormalizeIncidentID — 9 cases covering INC-prefix, UUIDs, slugs, edge cases
  • TestRunGetNormalizesSequentialID — verifies API receives /v1/incidents/42 when given INC-42
  • TestRunGetAcceptsUUID — verifies UUIDs pass through unchanged
  • All existing tests pass (delete/update messages preserved)
  • E2E verified against real API: rootly incidents get INC-31 returns correct incident

The Rootly API accepts UUID, slug, or bare numeric sequential ID but
not the "INC-123" display format. NormalizeIncidentID strips the prefix
so `rootly incidents get INC-31` hits /v1/incidents/31 instead of
/v1/incidents/INC-31 which 404'd.

Closes #28

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Jun 4, 2026

Greptile Summary

This PR fixes rootly incidents get/update/delete INC-xxx commands that were failing because the CLI was passing the INC- prefix verbatim to an API that only accepts a bare numeric sequential ID, UUID, or slug.

  • Adds NormalizeIncidentID() in internal/api/client.go using a compiled case-insensitive regex to strip the INC- prefix from sequential IDs; UUIDs, slugs, and bare numbers pass through unchanged.
  • Applies normalization to get, update, and delete commands; delete and update correctly separate displayID from the normalized incidentID so confirmation prompts and success messages still show the original INC-xxx format.
  • Adds 9-case unit tests for the normalizer and two integration tests verifying the correct API path is called for both sequential IDs and UUIDs.

Confidence Score: 4/5

Safe to merge; the core normalization logic is correct and well-tested, with only a minor UX inconsistency in how error messages for get surface the original ID.

The normalization regex, its placement, and the split between displayID/incidentID in delete and update are all correct. The one gap is get.go, which discards the original input before the API call — so a 404 error message will reference the bare number rather than the user-supplied INC-xxx. This is a display inconsistency rather than a functional bug, but it goes against the PR's own stated goal of preserving the user-facing format.

internal/cmd/incidents/get.go — the original input ID is not retained for error message display

Important Files Changed

Filename Overview
internal/api/client.go Adds NormalizeIncidentID pure utility function with a compiled regex; correctly strips INC- prefix (case-insensitive) from sequential IDs while leaving UUIDs and slugs untouched
internal/cmd/incidents/get.go Applies normalization before the API call; original input is not preserved, so 404 error messages will show the bare number ("999") instead of the user-supplied "INC-999"
internal/cmd/incidents/delete.go Correctly separates displayID from incidentID; confirmation prompt and success message use the original INC-xxx format
internal/cmd/incidents/update.go Correctly separates displayID from incidentID; success message uses the original INC-xxx format
internal/cmd/incidents/cmd_test.go Adds integration tests verifying normalization for get; covers sequential ID and UUID pass-through paths
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
internal/cmd/incidents/get.go:39-40
The PR's stated goal is for user-facing messages to keep the original `INC-xxx` format, and `delete`/`update` both achieve this via a separate `displayID`. In `runGet`, only the normalized `id` is stored, so a 404 error bubbles up as `"failed to get incident: incident not found: 999"` rather than `"incident not found: INC-999"`. Storing the original input and using it in the error wrapping keeps the UX consistent.

```suggestion
func runGet(cmd *cobra.Command, args []string) error {
	displayID := args[0]
	id := api.NormalizeIncidentID(displayID)
```

Reviews (1): Last reviewed commit: "🐛 fix: resolve incidents get/update/del..." | Re-trigger Greptile

Comment thread internal/cmd/incidents/get.go Outdated
Comment on lines +39 to +40
func runGet(cmd *cobra.Command, args []string) error {
// Get incident ID from args
id := args[0]
id := api.NormalizeIncidentID(args[0])
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 The PR's stated goal is for user-facing messages to keep the original INC-xxx format, and delete/update both achieve this via a separate displayID. In runGet, only the normalized id is stored, so a 404 error bubbles up as "failed to get incident: incident not found: 999" rather than "incident not found: INC-999". Storing the original input and using it in the error wrapping keeps the UX consistent.

Suggested change
func runGet(cmd *cobra.Command, args []string) error {
// Get incident ID from args
id := args[0]
id := api.NormalizeIncidentID(args[0])
func runGet(cmd *cobra.Command, args []string) error {
displayID := args[0]
id := api.NormalizeIncidentID(displayID)
Prompt To Fix With AI
This is a comment left during a code review.
Path: internal/cmd/incidents/get.go
Line: 39-40

Comment:
The PR's stated goal is for user-facing messages to keep the original `INC-xxx` format, and `delete`/`update` both achieve this via a separate `displayID`. In `runGet`, only the normalized `id` is stored, so a 404 error bubbles up as `"failed to get incident: incident not found: 999"` rather than `"incident not found: INC-999"`. Storing the original input and using it in the error wrapping keeps the UX consistent.

```suggestion
func runGet(cmd *cobra.Command, args []string) error {
	displayID := args[0]
	id := api.NormalizeIncidentID(displayID)
```

How can I resolve this? If you propose a fix, please make it concise.

Keeps displayID separate from normalized ID in runGet, consistent with
update and delete commands. Error now shows "failed to get incident
INC-999" instead of bare "999".

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@kwent kwent merged commit 8d04697 into master Jun 4, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

incidents get {ID} fails

1 participant