integrations / integrations/terraform-provider-github

github_repository Read doesn't refresh id/name after an out-of-band rename (unlike Create/Update)

Open Beginner friendly
#3,592 2 comments 0 reactions 0 assignees View on GitHub
r/repository Type: Bug
Dominant language
Go
Stars
1.2k
Forks
1k
Avg merge
1d 14h
Merged PRs (30d)
8

Description

## Terraform Version

1.5.7 (and later, unaffected by TF core version)

## Provider Version

v6.11.1 (confirmed still present at v6.13.0, the latest release as of this report)

## Affected Resource(s)

- github_repository

## Terraform Configuration Files

N/A — reproduces on any `github_repository` resource that is renamed out-of-band (i.e. `name` changes on an already-applied resource) between two `terraform apply`/`terraform plan -refresh-only` runs.

## Expected Behavior

After a rename, `terraform refresh`/`plan` should observe the *actual current* repository name and either report no diff (if the config's `name` already matches) or a correct diff.

## Actual Behavior

`resourceGithubRepositoryRead` (`github/resource_github_repository.go`) does:

```go
repoName := d.Id()
...
repo, resp, err := client.Repositories.Get(ctx, owner, repoName)
...
_ = d.Set("name", repoName)
```

`client.Repositories.Get` succeeds even when `repoName` is the *old* name, because the GitHub API transparently redirects a renamed repository's old-name lookup to the current one — `repo` in the response correctly reflects the new name (`repo.GetName()`), and every other field is set from that response (`repo.GetDescription()`, `repo.GetFullName()`, etc.). But `name` is set from the pre-read `repoName` local variable instead of `repo.GetName()`, so it never reflects the actual current name. `Read` also never calls `d.SetId(...)`, so the resource's ID likewise never advances past the original name.

By contrast, both `resourceGithubRepositoryCreate` and `resourceGithubRepositoryUpdate` correctly call `d.SetId(repo.GetName())` after their respective API calls (Update even has a comment noting exactly this hazard: "It's possible that `repo.GetName()` is different from `repoName` if the repository is renamed"). That same handling was never applied to Read.

Practical impact for consumers that track external identity by ID/name (e.g. Crossplane's upjet-based providers, which re-derive their external-name annotation from the Terraform ID on every reconcile): once a repository is renamed, `Read` keeps reporting the pre-rename name indefinitely, and any control loop that treats that as authoritative will keep trying to "correct" the live repository back to its old name.

## Steps to Reproduce

1. `terraform apply` a `github_repository` resource, e.g. `name = "foo"`.
2. Rename the repository out-of-band (GitHub UI, or `gh repo rename bar -R owner/foo`), so the live repo is now `owner/bar` but the Terraform ID in state is still `foo`.
3. `terraform plan -refresh-only` (or any `Read`/`RefreshWithoutUpgrade` invocation using the stale ID).
4. Observe: the read succeeds (via GitHub's redirect), but the refreshed `name` attribute (and the resource's ID) still shows `foo`, not `bar`.

## Suggested fix

In `resourceGithubRepositoryRead`, immediately after the `client.Repositories.Get` call:

```go
d.SetId(repo.GetName())
...
_ = d.Set("name", repo.GetName())
```

mirroring the existing `Create`/`Update` handling.

Contributor guide

Open the contributing guide

Research direction

Read resourceGithubRepositoryRead in github/resource_github_repository.go first, then compare its name and ID handling with Create and Update. Verify completion by reproducing an out-of-band rename and confirming refresh observes repo.GetName() for both the name attribute and resource ID.

Written by the indexing model from the issue text.

Assessment

Tech stack
github, go, terraform
Domain
api, backend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.