Conversation
…lid resource IDs When using --source-id or --destination-id flags and the API returns a 404 Not Found error, the CLI now displays helpful hints about expected ID formats: - Source IDs typically start with 'src_' - Destination IDs typically start with 'des_' This helps users identify when they've provided the wrong type of ID (e.g., using a connection ID 'web_xxx' instead of a source ID 'src_xxx'). Fixes #204 Example output for the bug report scenario: ``` $ hookdeck connection create --name "my-conn" --source-id "web_y0A7nz0tRxZy" \ --destination-type HTTP --destination-name "my-dest" \ --destination-url "https://example.com" failed to create connection: error: Not Found Hints: - --source-id 'web_y0A7nz0tRxZy' was provided. Source IDs typically start with 'src_'. Please verify the resource IDs exist and are the correct type. ``` Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Pull request overview
This PR adds helpful error hints when connection create/upsert commands fail with 404 Not Found errors, helping users identify when they've provided incorrect resource ID types (e.g., using a connection ID instead of a source ID).
Changes:
- Added error enhancement logic that detects 404 errors and displays hints about expected ID format for
--source-idand--destination-idflags - Shared
enhanceConnectionError()method betweenconnection createandconnection upsertcommands - Added 6 acceptance tests covering error scenarios with non-existent IDs, wrong ID types, and a positive test case
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| pkg/cmd/connection_create.go | Added enhanceCreateError() and enhanceConnectionError() methods to detect 404 errors and provide helpful hints about resource ID formats |
| pkg/cmd/connection_upsert.go | Updated error handling to use the shared enhanceConnectionError() method from the embedded connectionCreateCmd |
| test/acceptance/connection_error_hints_test.go | Added comprehensive acceptance tests covering error scenarios with non-existent source/destination IDs, wrong ID types, and valid existing source ID usage |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| hints = append(hints, fmt.Sprintf(" - --source-id '%s' was provided. Source IDs typically start with 'src_'.", cc.sourceID)) | ||
| } | ||
| if cc.destinationID != "" { | ||
| hints = append(hints, fmt.Sprintf(" - --destination-id '%s' was provided. Destination IDs typically start with 'des_'.", cc.destinationID)) |
There was a problem hiding this comment.
The destination ID prefix in the hint message is incorrect. According to the documentation (REFERENCE.md:906) and unit tests (pkg/hookdeck/connections_test.go:270), destination IDs use the prefix 'dest_', not 'des_'. The hint message should say "Destination IDs typically start with 'dest_'." to be consistent with the actual API.
| hints = append(hints, fmt.Sprintf(" - --destination-id '%s' was provided. Destination IDs typically start with 'des_'.", cc.destinationID)) | |
| hints = append(hints, fmt.Sprintf(" - --destination-id '%s' was provided. Destination IDs typically start with 'dest_'.", cc.destinationID)) |
There was a problem hiding this comment.
@copilot you are incorrect. destination IDs start with des_. Where did you get your information from?

|
|
||
| connName := "test-bad-dst-" + timestamp | ||
| sourceName := "test-src-" + timestamp | ||
| fakeDestinationID := "des_nonexistent123" |
There was a problem hiding this comment.
The fake destination ID uses an incorrect prefix. According to the documentation (REFERENCE.md:906) and unit tests (pkg/hookdeck/connections_test.go:270), destination IDs should use the prefix 'dest_', not 'des_'. Change this to "dest_nonexistent123" to match the actual API format.
| assert.Contains(t, combinedOutput, "Hints:", "Should contain hints section") | ||
| assert.Contains(t, combinedOutput, "--destination-id", "Hint should mention --destination-id flag") | ||
| assert.Contains(t, combinedOutput, fakeDestinationID, "Hint should include the provided destination ID") | ||
| assert.Contains(t, combinedOutput, "des_", "Hint should mention destination ID prefix format") |
There was a problem hiding this comment.
The test assertion checks for the incorrect prefix 'des_'. According to the documentation (REFERENCE.md:906) and unit tests (pkg/hookdeck/connections_test.go:270), destination IDs should use the prefix 'dest_', not 'des_'. Update this assertion to check for "dest_" instead.
| assert.Contains(t, combinedOutput, "des_", "Hint should mention destination ID prefix format") | |
| assert.Contains(t, combinedOutput, "dest_", "Hint should mention destination ID prefix format") |
|
|
||
| connName := "test-upsert-bad-dst-" + timestamp | ||
| sourceName := "test-src-" + timestamp | ||
| fakeDestinationID := "des_nonexistent456" |
There was a problem hiding this comment.
The fake destination ID uses an incorrect prefix. According to the documentation (REFERENCE.md:906) and unit tests (pkg/hookdeck/connections_test.go:270), destination IDs should use the prefix 'dest_', not 'des_'. Change this to "dest_nonexistent456" to match the actual API format.
| assert.Contains(t, combinedOutput, "Hints:", "Should contain hints section") | ||
| assert.Contains(t, combinedOutput, "--destination-id", "Hint should mention --destination-id flag") | ||
| assert.Contains(t, combinedOutput, fakeDestinationID, "Hint should include the provided destination ID") | ||
| assert.Contains(t, combinedOutput, "des_", "Hint should mention destination ID prefix format") |
There was a problem hiding this comment.
The test assertion checks for the incorrect prefix 'des_'. According to the documentation (REFERENCE.md:906) and unit tests (pkg/hookdeck/connections_test.go:270), destination IDs should use the prefix 'dest_', not 'des_'. Update this assertion to check for "dest_" instead.
| assert.Contains(t, combinedOutput, "des_", "Hint should mention destination ID prefix format") | |
| assert.Contains(t, combinedOutput, "dest_", "Hint should mention destination ID prefix format") |
| require.NotEmpty(t, initialConn.ID, "Initial connection should have ID") | ||
|
|
||
| // Get the source ID from the created connection | ||
| sourceID := initialConn.Source.Name // We need the actual source ID, not name |
There was a problem hiding this comment.
This line is unnecessary and creates dead code. The variable sourceID is immediately reassigned on line 221 after fetching the connection details. The comment on this line even acknowledges this is incorrect ("We need the actual source ID, not name"). Remove this line and the comment, and declare sourceID as var sourceID string instead.
| sourceID := initialConn.Source.Name // We need the actual source ID, not name | |
| var sourceID string |
|
@leggetter I've opened a new pull request, #206, to work on those changes. Once the pull request is ready, I'll request review from you. |
Co-authored-by: leggetter <328367+leggetter@users.noreply.github.com>
Co-authored-by: leggetter <328367+leggetter@users.noreply.github.com>
fix: correct destination ID prefix from dest_ to des_ across codebase
Remove unnecessary sourceID assignment that was immediately overwritten. Co-authored-by: Cursor <cursoragent@cursor.com>
Summary
Fixes #204
When using
--source-idor--destination-idflags and the API returns a 404 Not Found error, the CLI now displays helpful hints about expected ID formats to help users identify when they've provided the wrong type of ID.Changes
enhanceConnectionError()shared method inconnection_create.gothat detects 404/Not Found errors--source-idor--destination-idis provided and an error occurs, displays hints about ID formatsconnection createandconnection upsertcommands share the same logicExample Output
For the bug report scenario where a connection ID (
web_) was mistakenly used instead of a source ID (src_):Test Plan
Made with Cursor