cli: `gh codespace list` shows an instance, but I cannot delete it

Describe the bug

gh version 2.33.0 (2023-08-18)
https://github.com/cli/cli/releases/tag/v2.33.0

When I list my codespaces in my org, I see one that is in a shutdown state, however when I go to delete it via the CLI, I get told I have no codespaces.

Steps to reproduce the behavior

$ gh codespace list --org MY_ORG
NAME                            DISPLAY NAME   OWNER       REPOSITORY                           BRANCH  STATE     CREATED AT
humble-engine-65rjvwpjgr63r9p5  humble engine  USERNAME  MY_ORG/technical-interview  main*   Shutdown  16h

$ gh codespace delete --user USERNAME
error choosing codespace: you have no codespaces

Expected vs actual behavior

I expect that I can delete a codespace that is in the result of the list codespaces command

About this issue

  • Original URL
  • State: closed
  • Created 10 months ago
  • Comments: 19 (9 by maintainers)

Most upvoted comments

There’s definitely a bug here. I’m following up with the team to find out whether this is an issue on the org-level REST API, or whether the CLI is not using the org-level APIs in the expected way.

It’s related to how the APIs behave when the user is no longer a member of the org, and thus the codespace is no longer visible to the user. When the CLI is making the call to https://api.github.com/orgs/snowfall-travel/members/USER/codespaces?per_page=100, that endpoint currently only shows codespaces that are visible to the USER, which it’s not because they have been removed. That’s different behavior from both the non-user-scoped org-level list endpoint as well as the delete endpoint which allows you to see and act on codespaces that are not visible to the end user.

I would expect the https://api.github.com/orgs/snowfall-travel/members/USER/codespaces?per_page=100 endpoint to work similarly to the other org APIs and show codespaces even if they are not currently visible to the end user. But I also think the CLI doesn’t need to make that API call in this scenario since it already knows the codespace name, org, and user. The CLI should be able to directly call the delete endpoint which should work.

Thanks for the extra details. Just to double check because you used USER and USERNAME interchangeably, this is just you manually redacting the name of the candidate right?

I moved to using the CLI as it seemed to be the most consistent in finding codespaces that interviewees had started up, especially for deleting them

I’m sure we’ll be able to figure this out for you.

$ GH_DEBUG=api GH_PAGER="" gh codespace delete --org snowfall-travel -c humble-engine-65rjvwpjgr63r9p5
using `--org` with `--codespace` requires `--user`

$ GH_DEBUG=api GH_PAGER="" gh codespace delete --org snowfall-travel -c humble-engine-65rjvwpjgr63r9p5 --user USER
Fetching codespace ⣾* Request at 2023-08-30 09:51:35.78898 +0100 BST m=+0.057926709
* Request to https://api.github.com/orgs/snowfall-travel/members/USER/codespaces?per_page=100
> GET /orgs/snowfall-travel/members/USER/codespaces?per_page=100 HTTP/1.1
> Host: api.github.com
> Accept: application/vnd.github.v3+json
> Authorization: token ████████████████████
> Content-Type: application/json; charset=utf-8
> Time-Zone: Europe/London
> User-Agent: GitHub CLI 2.33.0

Fetching codespace ⣻< HTTP/2.0 200 OK
< Access-Control-Allow-Origin: *
< Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
< Cache-Control: private, max-age=60, s-maxage=60
< Content-Security-Policy: default-src 'none'
< Content-Type: application/json; charset=utf-8
< Date: Wed, 30 Aug 2023 08:51:35 GMT
< Etag: W/"12f5fc0e889fec45f97be526643a46826dc17ba360e263d0c72a4638dc45d33f"
< Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
< Server: GitHub.com
< Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
< Vary: Accept, Authorization, Cookie, X-GitHub-OTP
< Vary: Accept-Encoding, Accept, X-Requested-With
< X-Accepted-Oauth-Scopes: admin:org
< X-Content-Type-Options: nosniff
< X-Frame-Options: deny
< X-Github-Api-Version-Selected: 2022-11-28
< X-Github-Media-Type: github.v3; format=json
< X-Github-Request-Id: EB48:B2B6:2DF6758:2E6AA16:64EF0317
< X-Oauth-Client-Id: 178c6fc778ccc68e1d6a
< X-Oauth-Scopes: admin:org, admin:public_key, codespace, gist, repo
< X-Ratelimit-Limit: 5000
< X-Ratelimit-Remaining: 4979
< X-Ratelimit-Reset: 1693386173
< X-Ratelimit-Resource: codespaces
< X-Ratelimit-Used: 21
< X-Xss-Protection: 0

{
  "codespaces": [],
  "total_count": 0
}

* Request took 263.685459ms
error fetching codespace information: codespace not found for user USER with name humble-engine-65rjvwpjgr63r9p5

Sorry @ciaranevans I mean GH_DEBUG=api!

Hey @williammartin !

Sure, let me get those for you.

Well, I am one of the Org owners and this user was invited to one repo for a technical interview, I’ve been able to delete others codespaces in this scenario till now.