Skip to content

gh gist edit can panic index of range when no file in a gist #10626

Description

@phanen

Describe the bug

bash repro.sh:

echo foo | gh gist create

cat <<EOF >dummy_editor
#!/bin/sh
printf '' > "\$1"
EOF

chmod +x dummy_editor

# make file "foo" empty (seems deleting the file from gist)
GH_EDITOR=$(realpath dummy_editor) ./bin/gh gist edit "$(gh gist list | head -1 | awk '{ print $1 }')"
./bin/gh gist edit # panic

Then panic with:

goroutine 1 [running]:
github.com/cli/cli/v2/pkg/cmd/gist/shared.Gist.Filename({{0xc000c020a0, 0x20}, {0x0, 0x0}, 0xc000c06690, {0x0, 0xedf6b06e9, 0x0}, 0x0, {0x0, ...}, ...})
        github.com/cli/cli/v2/pkg/cmd/gist/shared/shared.go:48 +0x176
github.com/cli/cli/v2/pkg/cmd/gist/shared.PromptGists({0x2414f20, 0xc00061c5f0}, 0xf?, {0xc0003ff020?, 0x1?}, 0xc00038a71a)
        github.com/cli/cli/v2/pkg/cmd/gist/shared/shared.go:233 +0x1b8
github.com/cli/cli/v2/pkg/cmd/gist/edit.editRun(0xc00046f4d0)
        github.com/cli/cli/v2/pkg/cmd/gist/edit/edit.go:115 +0x105
github.com/cli/cli/v2/pkg/cmd/gist/edit.NewCmdEdit.func3(0xc000671208?, {0x2f72940?, 0x4?, 0x17fc4f0?})
        github.com/cli/cli/v2/pkg/cmd/gist/edit/edit.go:79 +0x98
github.com/spf13/cobra.(*Command).execute(0xc000671208, {0x2f72940, 0x0, 0x0})
        github.com/spf13/[email protected]/command.go:985 +0xaaa
github.com/spf13/cobra.(*Command).ExecuteC(0xc0005ac908)
        github.com/spf13/[email protected]/command.go:1117 +0x3ff
github.com/spf13/cobra.(*Command).ExecuteContextC(...)
        github.com/spf13/[email protected]/command.go:1050
github.com/cli/cli/v2/internal/ghcmd.Main()
        github.com/cli/cli/v2/internal/ghcmd/cmd.go:119 +0x53b
main.main()
        github.com/cli/cli/v2/cmd/gh/main.go:10 +0x13

Affected version

Test on 2.65.0 and HEAD, both reproduced.

Expected vs actual behavior

No panic.

Activity

  1. phanen commented on Mar 18, 2025

    @phanen
    ContributorAuthor

    Create a PR fix this #10627.

    But I'm not sure what is a "no file" gist. This type of gist cannot be created on webpage (only by cli), since on web when I click "delete file", the gist will be totally deleted and won't be listed in gh gist list

  2. added
    priority-3Affects a small number of users or is largely cosmetic
    gh-gistrelating to the gh gist command
    on Mar 18, 2025
  3. williammartin commented on Mar 18, 2025

    @williammartin
    Member

    Thanks for creating this issue.

    It's interesting that gh gist edit is able to remove files by setting the content of the file to the empty string (here's the API request):

    * Request to https://api.github.com/gists/be741267949d71020b059a3037937903
    > POST /gists/be741267949d71020b059a3037937903 HTTP/1.1
    > Host: api.github.com
    > Accept: application/vnd.github.merge-info-preview+json, application/vnd.github.nebula-preview
    > Authorization: token ████████████████████
    > Content-Length: 88
    > Content-Type: application/json; charset=utf-8
    > Time-Zone: Europe/Amsterdam
    > User-Agent: GitHub CLI 2.68.0
    
    {
      "description": "",
      "files": {
        "gistfile0.txt": {
          "content": "\n",
          "filename": "gistfile0.txt"
        }
      }
    }
    

    The docs say:

    To delete a file, set the whole file to null. For example: hello.py : null. The file will also be deleted if the specified object does not contain at least one of content or filename.

    Neither of those seem true 🤷 Maybe something I'll raise with the API team.

    In any case, since it seems currently possible in the API to end up with a gist that has no files, I agree we should fix the panic regardless. Note that gist view, gist delete also panic:

    ➜  cli-triaging gh gist view
    panic: runtime error: index out of range [0] with length 0
    
    goroutine 1 [running]:
    github.com/cli/cli/v2/pkg/cmd/gist/shared.Gist.Filename({{0x14000421ee0, 0x20}, {0x0, 0x0}, 0x1400029dce0, {0x0, 0xedf6b6085, 0x0}, 0x0, {0x0, ...}, ...})
            github.com/cli/cli/v2/pkg/cmd/gist/shared/shared.go:48 +0x1a0
    github.com/cli/cli/v2/pkg/cmd/gist/shared.PromptGists({0x104989b60, 0x140004ff1d0}, 0x0?, {0x103a00b4b?, 0x0?}, 0x1400000fbca)
            github.com/cli/cli/v2/pkg/cmd/gist/shared/shared.go:233 +0x16c
    github.com/cli/cli/v2/pkg/cmd/gist/view.viewRun(0x1400051f260)
            github.com/cli/cli/v2/pkg/cmd/gist/view/view.go:96 +0xe8
    github.com/cli/cli/v2/pkg/cmd/gist/view.NewCmdView.func1(0x1400013cf08?, {0x105479100?, 0x4?, 0x1039f0851?})
            github.com/cli/cli/v2/pkg/cmd/gist/view/view.go:64 +0xa4
    github.com/spf13/cobra.(*Command).execute(0x1400013cf08, {0x105479100, 0x0, 0x0})
            github.com/spf13/[email protected]/command.go:985 +0x830
    github.com/spf13/cobra.(*Command).ExecuteC(0x140009d6908)
            github.com/spf13/[email protected]/command.go:1117 +0x344
    github.com/spf13/cobra.(*Command).ExecuteContextC(...)
            github.com/spf13/[email protected]/command.go:1050
    github.com/cli/cli/v2/internal/ghcmd.Main()
            github.com/cli/cli/v2/internal/ghcmd/cmd.go:119 +0x4b0
    main.main()
            github.com/cli/cli/v2/cmd/gh/main.go:10 +0x1c
    
    ➜  cli-triaging gh gist delete
    panic: runtime error: index out of range [0] with length 0
    
    goroutine 1 [running]:
    github.com/cli/cli/v2/pkg/cmd/gist/shared.Gist.Filename({{0x14000501440, 0x20}, {0x0, 0x0}, 0x140002680c0, {0x0, 0xedf6b6085, 0x0}, 0x0, {0x0, ...}, ...})
            github.com/cli/cli/v2/pkg/cmd/gist/shared/shared.go:48 +0x1a0
    github.com/cli/cli/v2/pkg/cmd/gist/shared.PromptGists({0x106771b60, 0x14000595db0}, 0x1063c4640?, {0x1057e8b4b?, 0x0?}, 0x1400027225a)
            github.com/cli/cli/v2/pkg/cmd/gist/shared/shared.go:233 +0x16c
    github.com/cli/cli/v2/pkg/cmd/gist/delete.deleteRun(0x1400036a1c0)
            github.com/cli/cli/v2/pkg/cmd/gist/delete/delete.go:103 +0xf4
    github.com/cli/cli/v2/pkg/cmd/gist/delete.NewCmdDelete.func1(0x140006f1508?, {0x107261100, 0x0, 0x1057d8851?})
            github.com/cli/cli/v2/pkg/cmd/gist/delete/delete.go:71 +0xd4
    github.com/spf13/cobra.(*Command).execute(0x140006f1508, {0x107261100, 0x0, 0x0})
            github.com/spf13/[email protected]/command.go:985 +0x830
    github.com/spf13/cobra.(*Command).ExecuteC(0x14000274908)
            github.com/spf13/[email protected]/command.go:1117 +0x344
    github.com/spf13/cobra.(*Command).ExecuteContextC(...)
            github.com/spf13/[email protected]/command.go:1050
    github.com/cli/cli/v2/internal/ghcmd.Main()
            github.com/cli/cli/v2/internal/ghcmd/cmd.go:119 +0x4b0
    main.main()
            github.com/cli/cli/v2/cmd/gh/main.go:10 +0x1c
    

    Acceptance Criteria

    Given I have a gist with no files
    When I run gh gist view, gh gist edit or gh gist delete
    Then they should function normally and not panic

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

    bugSomething isn't workinggh-gistrelating to the gh gist commandhelp wantedContributions welcomepriority-3Affects a small number of users or is largely cosmetic

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions