Skip to content

Allow nil request body for non-GET request #3937

Description

@reybard

Describe the feature or problem you’d like to solve

We experienced an issue when trying to delete a package version via the GH API using the cli:

gh api -X DELETE /orgs/dsp-testing/packages/container/codeql-integration-testing-package/versions/1862941
{
  "message": "Invalid request.\n\nFor 'links/1/schema', {} is not a null.",
gh: Invalid request.
For 'links/1/schema', {} is not a null. (HTTP 422)
  "documentation_url": "https://docs.github.com/rest/reference/packages#delete-a-package-version-for-an-organization"
}

This happens because the CLI tries to send {} in the absence of any other defined fields for a request with a method other than GET. This is an issue for this endpoint (and possibly others) that use validators such as JSON-schema that mandate a request body be null.

Proposed solution

There are many ways to handle this including:

  1. Creating a new flag to represent a nil response body (such as --no-fields).
  2. Adding a reserved value for field such as "" that the CLI understands to mean give back nil (probably not advised)

But I think the optimal solution is the one that would be the most intuitive and least friction to users: assume nil and not {} when no fields are given.

I believe the problem spot lies at:

params := make(map[string]interface{})

Though it may take some refactoring elsewhere it could be as simple as having params returned as nil if no fields were parsed out.

Additional context

cURL example showing the same error:

» curl -H "Authorization: Bearer $GH_ADMIN_TOKEN" -X DELETE -d '{}' "https://api.github.com/orgs/sweethaven-village/packages/container/memcached/versions/778988"
{
  "message": "Invalid request.\n\nFor 'links/1/schema', {} is not a null.",
  "documentation_url": "https://docs.github.com/rest/reference/packages#delete-a-package-version-for-an-organization"
}

Activity

  1. vilmibm commented on Jul 12, 2021

    @vilmibm
    Contributor

    I'm fine with nil instead of {} when no fields would be sent, but off the top of my head can't predict if that will break other endpoints which might expect an empty object instead of nil.

    If someone is up for an exploratory PR + QA to see how well that works that would be great.

  2. mislav commented on Sep 7, 2021

    @mislav
    Contributor

    I think it should be safe to send an empty body instead of {}, even though it would be a backwards-incompatible change. Based on my informal inspection of the GitHub API, the endpoints that expect no arguments don't enforce that the input object must be {}. But, I'd need to take a deeper dive to confirm.

    As a potential workaround for this problem until a gh release that fixes this, I think the following might work:

    echo -n | gh api --method DELETE path/to/endpoint --input -
    
  3. ferferga commented on Sep 7, 2021

    @ferferga

    I think it should be safe to send an empty body instead of {}, even though it would be a backwards-incompatible change. Based on my informal inspection of the GitHub API, the endpoints that expect no arguments don't enforce that the input object must be {}. But, I'd need to take a deeper dive to confirm.

    As a potential workaround for this problem until a gh release that fixes this, I think the following might work:

    echo -n | gh api --method DELETE path/to/endpoint --input -
    

    I confirm that this fixes the issue, at least for the /packages/container/x/versions/x endpoint with DELETE.

  4. mislav commented on Mar 31, 2022

    @mislav
    Contributor

    From my cursory inspection of the JSON schema of our REST API endpoints, I do not think that sending an empty body instead of {} will break anything. This is now open to contributions — your starting point could be here:

    cli/pkg/cmd/api/http.go

    Lines 44 to 48 in a6f6ad7

    b, err := json.Marshal(pp)
    if err != nil {
    return nil, fmt.Errorf("error serializing parameters: %w", err)
    }
    body = bytes.NewBuffer(b)

    If len(pp) == 0, we could use an empty body instead of allowing the body to be encoded as {} in JSON.

  5. added
    priority-2Affects more than a few users but doesn't prevent core functions
    and removed
    needs-designAn engineering task needs design to proceed
    on Mar 31, 2022
  6. sgrigorjev commented on Jan 27, 2025

    @sgrigorjev

    If anyone is still suffering from this problem, here is a working solution:

    gh api --method DELETE --input /dev/null "/orgs/$ORG_NAME/packages/container/$PACKAGE_NAME/versions/$VERSION_ID"
    
  7. kewalaka commented on Apr 26, 2025

    @kewalaka

    If anyone is still suffering from this problem, here is a working solution:

    gh api --method DELETE --input /dev/null "/orgs/$ORG_NAME/packages/container/$PACKAGE_NAME/versions/$VERSION_ID"
    

    I think this should be in the docs!

    https://docs.github.com/en/rest/packages/packages?apiVersion=2022-11-28#delete-a-package-version-for-the-authenticated-user

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementa request to improve CLIhelp wantedContributions welcomepriority-2Affects more than a few users but doesn't prevent core functions

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions