[GH-ISSUE #517] Submit cancel: --id path uses deprecated endpoint and fails to cancel review submissions #141

Closed
opened 2026-02-26 21:33:44 +03:00 by kerem · 3 comments
Owner

Originally created by @rudrankriyam on GitHub (Feb 14, 2026).
Original GitHub issue: https://github.com/rudrankriyam/App-Store-Connect-CLI/issues/517

Summary

asc submit cancel --id <review_submission_id> --confirm currently routes through the legacy appStoreVersionSubmissions delete path instead of the reviewSubmissions cancel path.

Why this matters

Users who provide a valid review submission ID can get a misleading "not found" failure, even though the submission exists and is cancelable via the modern endpoint.

Current behavior

In internal/cli/submit/submit.go, the --id branch sets resolvedSubmissionID and immediately calls:

  • DeleteAppStoreVersionSubmission(...)

The CancelReviewSubmission(...) branch is only reached when resolvedSubmissionID == "", which does not happen for --id input.

Reproduction

  1. Create a review submission with asc submit create ... --confirm and capture the returned submission ID.
  2. Run:
    asc submit cancel --id "<review_submission_id>" --confirm
    
  3. Observe failure via old endpoint behavior instead of canceling the review submission.

Expected behavior

  • --id should target reviewSubmissions cancel semantics.
  • --version-id may continue using legacy lookup for old flows, but once a review submission ID is known, cancellation should use CancelReviewSubmission.

Detailed implementation plan

  • Refactor SubmitCancelCommand flow in internal/cli/submit/submit.go.
  • Route explicit --id to client.CancelReviewSubmission.
  • Keep --version-id resolution behavior, but cancel through review submission when available.
  • Improve errors to clearly distinguish "legacy submission not found" vs "review submission not found".
  • Add/extend tests in internal/cli/submit/submit_test.go and cmdtests for both selector modes.

Acceptance criteria

  • asc submit cancel --id <review_submission_id> --confirm successfully cancels review submissions.
  • --version-id flow remains functional and returns clear errors when no submission exists.
  • Exit codes/messages remain consistent with CLI policy.

cc @cursor please implement this end-to-end.

Originally created by @rudrankriyam on GitHub (Feb 14, 2026). Original GitHub issue: https://github.com/rudrankriyam/App-Store-Connect-CLI/issues/517 ## Summary `asc submit cancel --id <review_submission_id> --confirm` currently routes through the legacy `appStoreVersionSubmissions` delete path instead of the `reviewSubmissions` cancel path. ## Why this matters Users who provide a valid review submission ID can get a misleading "not found" failure, even though the submission exists and is cancelable via the modern endpoint. ## Current behavior In `internal/cli/submit/submit.go`, the `--id` branch sets `resolvedSubmissionID` and immediately calls: - `DeleteAppStoreVersionSubmission(...)` The `CancelReviewSubmission(...)` branch is only reached when `resolvedSubmissionID == ""`, which does not happen for `--id` input. ## Reproduction 1. Create a review submission with `asc submit create ... --confirm` and capture the returned submission ID. 2. Run: ```bash asc submit cancel --id "<review_submission_id>" --confirm ``` 3. Observe failure via old endpoint behavior instead of canceling the review submission. ## Expected behavior - `--id` should target `reviewSubmissions` cancel semantics. - `--version-id` may continue using legacy lookup for old flows, but once a review submission ID is known, cancellation should use `CancelReviewSubmission`. ## Detailed implementation plan - [ ] Refactor `SubmitCancelCommand` flow in `internal/cli/submit/submit.go`. - [ ] Route explicit `--id` to `client.CancelReviewSubmission`. - [ ] Keep `--version-id` resolution behavior, but cancel through review submission when available. - [ ] Improve errors to clearly distinguish "legacy submission not found" vs "review submission not found". - [ ] Add/extend tests in `internal/cli/submit/submit_test.go` and cmdtests for both selector modes. ## Acceptance criteria - [ ] `asc submit cancel --id <review_submission_id> --confirm` successfully cancels review submissions. - [ ] `--version-id` flow remains functional and returns clear errors when no submission exists. - [ ] Exit codes/messages remain consistent with CLI policy. cc @cursor please implement this end-to-end.
kerem 2026-02-26 21:33:44 +03:00
  • closed this issue
  • added the
    bug
    label
Author
Owner

@rudrankriyam commented on GitHub (Feb 14, 2026):

@cursor please implement this issue end-to-end using the checklist and acceptance criteria.

<!-- gh-comment-id:3900361474 --> @rudrankriyam commented on GitHub (Feb 14, 2026): @cursor please implement this issue end-to-end using the checklist and acceptance criteria.
Author
Owner

@cursor[bot] commented on GitHub (Feb 14, 2026):

Implemented end-to-end on cursor/submit-cancel-id-endpoint-2b2a and pushed as commit 1dd67bc.

  • I fixed submit cancel routing so explicit --id now uses CancelReviewSubmission (modern reviewSubmissions semantics), and no longer attempts legacy delete first.
  • I kept --version-id legacy lookup behavior, but now it tries review cancellation first when an ID is resolved, then falls back to legacy delete for old submission flows.
  • I improved error messaging to distinguish:
    • no review submission found for ID ... (for --id)
    • no legacy submission found for version ... / ...for ID ... (legacy path)
			resolvedSubmissionID := strings.TrimSpace(*submissionID)
			if resolvedSubmissionID != "" {
				_, err := client.CancelReviewSubmission(requestCtx, resolvedSubmissionID)
				if err != nil {
					if asc.IsNotFound(err) {
						return fmt.Errorf("submit cancel: no review submission found for ID %q", resolvedSubmissionID)
					}
					return fmt.Errorf("submit cancel: %w", err)
				}
			} else {
				resolvedVersionID := strings.TrimSpace(*versionID)

				// Resolve via legacy version submission lookup for backward compatibility.
				submissionResp, err := client.GetAppStoreVersionSubmissionForVersion(requestCtx, resolvedVersionID)
				if err != nil {
					if asc.IsNotFound(err) {
						return fmt.Errorf("submit cancel: no legacy submission found for version %q", resolvedVersionID)
					}
					return fmt.Errorf("submit cancel: %w", err)
				}
				resolvedSubmissionID = strings.TrimSpace(submissionResp.Data.ID)
				if resolvedSubmissionID == "" {
					return fmt.Errorf("submit cancel: no legacy submission found for version %q", resolvedVersionID)
				}

				// Prefer the modern reviewSubmissions cancel endpoint when possible.
				_, err = client.CancelReviewSubmission(requestCtx, resolvedSubmissionID)
				if err == nil {
					result := &asc.AppStoreVersionSubmissionCancelResult{
						ID:        resolvedSubmissionID,
						Cancelled: true,
					}
					return shared.PrintOutput(result, *output, *pretty)
				}
				if !asc.IsNotFound(err) {
					return fmt.Errorf("submit cancel: %w", err)
				}

				// Fall back to the legacy delete endpoint for old submission flows.
				if err := client.DeleteAppStoreVersionSubmission(requestCtx, resolvedSubmissionID); err != nil {
					if asc.IsNotFound(err) {
						return fmt.Errorf("submit cancel: no legacy submission found for ID %q", resolvedSubmissionID)
					}
					return fmt.Errorf("submit cancel: %w", err)
				}
			}

Testing and evidence:

  • Added/extended tests in both requested areas:
    • internal/cli/submit/submit_test.go (new routing + error-path coverage)
    • internal/cli/cmdtest/submit_cancel_test.go (root-command selector-mode behavior + output parsing)
  • Ran:
    • go test ./internal/cli/submit -run TestSubmitCancelCommand_ -count=1
    • go test ./internal/cli/cmdtest -run SubmitCancel -count=1
    • PATH="$PATH:/home/ubuntu/go/bin" make lint
    • make test
    • go build -o /tmp/asc . && /tmp/asc submit cancel --id "review-submission-123" (validated usage exit path; exit_code:2 when --confirm is missing)
  • Walkthrough artifact: /opt/cursor/artifacts/submit_cancel_selector_modes_tests_passing.mp4 (shows selector-mode tests passing).

View PR

Open in Cursor Open in Web

<!-- gh-comment-id:3900361616 --> @cursor[bot] commented on GitHub (Feb 14, 2026): Implemented end-to-end on `cursor/submit-cancel-id-endpoint-2b2a` and pushed as commit `1dd67bc`. - I fixed `submit cancel` routing so explicit `--id` now uses `CancelReviewSubmission` (modern `reviewSubmissions` semantics), and no longer attempts legacy delete first. - I kept `--version-id` legacy lookup behavior, but now it **tries review cancellation first** when an ID is resolved, then falls back to legacy delete for old submission flows. - I improved error messaging to distinguish: - `no review submission found for ID ...` (for `--id`) - `no legacy submission found for version ...` / `...for ID ...` (legacy path) ```262:306:internal/cli/submit/submit.go resolvedSubmissionID := strings.TrimSpace(*submissionID) if resolvedSubmissionID != "" { _, err := client.CancelReviewSubmission(requestCtx, resolvedSubmissionID) if err != nil { if asc.IsNotFound(err) { return fmt.Errorf("submit cancel: no review submission found for ID %q", resolvedSubmissionID) } return fmt.Errorf("submit cancel: %w", err) } } else { resolvedVersionID := strings.TrimSpace(*versionID) // Resolve via legacy version submission lookup for backward compatibility. submissionResp, err := client.GetAppStoreVersionSubmissionForVersion(requestCtx, resolvedVersionID) if err != nil { if asc.IsNotFound(err) { return fmt.Errorf("submit cancel: no legacy submission found for version %q", resolvedVersionID) } return fmt.Errorf("submit cancel: %w", err) } resolvedSubmissionID = strings.TrimSpace(submissionResp.Data.ID) if resolvedSubmissionID == "" { return fmt.Errorf("submit cancel: no legacy submission found for version %q", resolvedVersionID) } // Prefer the modern reviewSubmissions cancel endpoint when possible. _, err = client.CancelReviewSubmission(requestCtx, resolvedSubmissionID) if err == nil { result := &asc.AppStoreVersionSubmissionCancelResult{ ID: resolvedSubmissionID, Cancelled: true, } return shared.PrintOutput(result, *output, *pretty) } if !asc.IsNotFound(err) { return fmt.Errorf("submit cancel: %w", err) } // Fall back to the legacy delete endpoint for old submission flows. if err := client.DeleteAppStoreVersionSubmission(requestCtx, resolvedSubmissionID); err != nil { if asc.IsNotFound(err) { return fmt.Errorf("submit cancel: no legacy submission found for ID %q", resolvedSubmissionID) } return fmt.Errorf("submit cancel: %w", err) } } ``` Testing and evidence: - Added/extended tests in both requested areas: - `internal/cli/submit/submit_test.go` (new routing + error-path coverage) - `internal/cli/cmdtest/submit_cancel_test.go` (root-command selector-mode behavior + output parsing) - Ran: - `go test ./internal/cli/submit -run TestSubmitCancelCommand_ -count=1` - `go test ./internal/cli/cmdtest -run SubmitCancel -count=1` - `PATH="$PATH:/home/ubuntu/go/bin" make lint` - `make test` - `go build -o /tmp/asc . && /tmp/asc submit cancel --id "review-submission-123"` (validated usage exit path; `exit_code:2` when `--confirm` is missing) - Walkthrough artifact: **`/opt/cursor/artifacts/submit_cancel_selector_modes_tests_passing.mp4`** (shows selector-mode tests passing). <p><a href="https://github.com/rudrankriyam/App-Store-Connect-CLI/pull/535"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/view-pr-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/view-pr-light.png"><img alt="View PR" width="86" height="28" src="https://cursor.com/assets/images/view-pr-light.png"></picture></a></p> <p><a href="https://cursor.com/background-agent?bcId=bc-cd2f33b5-d863-4c83-8f75-f9f5718661af"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img alt="Open in Cursor" width="131" height="28" src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a>&nbsp;<a href="https://cursor.com/agents?id=bc-cd2f33b5-d863-4c83-8f75-f9f5718661af"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-web-light.png"><img alt="Open in Web" width="114" height="28" src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a></p>
Author
Owner

@rudrankriyam commented on GitHub (Feb 14, 2026):

Fixed in #535 (merged to main).

<!-- gh-comment-id:3900688706 --> @rudrankriyam commented on GitHub (Feb 14, 2026): Fixed in #535 (merged to main).
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
starred/App-Store-Connect-CLI#141
No description provided.