Cannot change default branch

Hi

I am having trouble with changing the default branch from master to new_branch using the api.

The error that I am getting is

{
“message”: “Validation Failed”,
“errors”: [
{
“message”: “The branch new_branch was not found. Please push that ref first or create it via the Git Data API.”,
“resource”: “Repository”,
“field”: “default_branch”,
“code”: “invalid”
}
],
“documentation_url”: “https://developer.github.com/enterprise/2.15/v3/repos/#edit
}

But I can change it on website. Is there a reason why I cannot do that using the API?

If I can change it on website, it should be the same when I change it using API, right?

I’ also tried to fetch the the branches of the repo using API and my target branch is there. then, there is no protection on those branches. 

JSON data passed:

{
“name” : “git_practice_1”,
“default_branch” : “devel”
}
PATCH request

Please let me know if you need more information.

I hope somebody can address my issue.

Thanks and more power.

3 Likes

I can’t say why you are running into this problem without being able to look at the repository in question. I would suspect that there is a typo somewhere that is messing things up.

I’m not sure what you mean by “there is no protection on those branches”, can you please give some more details?

1 Like

I am having the same exact problem. This is on a github enterprise, but I can copy/paste some output here:

Looking at existing branches:

$ hub api repos/rm-you/testrepo/branches | jq
[
  {
    "name": "master",
    "commit": {
      "sha": "5e1b32a925e4288b1e173d2e33e549baed3136f6",
      "url": "https://mygithub/api/v3/repos/rm-you/testrepo/commits/5e1b32a925e4288b1e173d2e33e549baed3136f6"
    }
  },
  {
    "name": "new_branch",
    "commit": {
      "sha": "ade39bea2d561bfb87a3e40cf55a0d4079540bef",
      "url": "https://mygithub/api/v3/repos/rm-you/testrepo/commits/ade39bea2d561bfb87a3e40cf55a0d4079540bef"
    }
  }
}

Which one is the default now?

$ hub api repos/rm-you/testrepo | jq .default_branch
"master"

Ok, let’s change it to “new_branch”:

$ hub api repos/rm-you/testrepo -X PATCH -F default_branch="new_branch" | jq
{
  "message": "Validation Failed",
  "errors": [
    {
      "message": "The branch new_branch was not found. Please push that ref first or create it via the Git Data API.",
      "resource": "Repository",
      "field": "default_branch",
      "code": "invalid"
    }
  ],
  "documentation_url": "https://developer.github.com/enterprise/2.15/v3/repos/#edit"
}

So, it failed to find the branch that it just listed. That’s … not great. :frowning:

As far as branch protections, I think they were implying that possibly branch protections could prohibit a branch from becoming the default, or from changing the default? I don’t think that’s the case however, so it shouldn’t matter. They were just adding some extra info. I actually do have protections set up on both the existing default branch and the new branch, but I don’t believe it should make a difference.

3 Likes

Same problem here  (branch not found, but it exists). And I’m unable to change even on the GitHub website :frowning:

On the Chrome Developer Console, it appears:

An invalid form control with name='name' is not focusable.
1 Like

If you’re experiencing this in the UI, open the branch selection element and check if there are two options simultaneously picked. This happened to me when I typed the branch name and pressed ENTER: two branches were selected at the same time.

Manually clicking the branch name wil de-select the other and you’ll be able to update the branch.

Could someone else possibly test this and confirm? If this API call is broken for everyone (as I expect it is), I wonder if it was recent, or if it is just so uncommonly used that no one noticed yet and actually bothered to complain. :smiley:

Following up, I decided to test this on public Github (really should have done this immediately, not sure why I didn’t) and the issue appears there as well.

For example, on this repo: https://github.com/rm-you/devstack_deploy

The default branch is master, and there exists a branch centos_new.

I tried setting centos_new as the default branch, but got the same error.

$ hub api repos/rm-you/devstack_deploy -X PATCH -F default_branch=centos_new
{"message":"Validation Failed","errors":[{"message":"The branch centos_new was not found. Please push that ref first or create it via the Git Data API.","resource":"Repository","field":"default_branch","code":"invalid"}],"documentation_url":"https://developer.github.com/v3/repos/#edit"}

I *was* able to set it as the default in the UI though, and then the API shows it as the default branch.

$ hub api repos/rm-you/devstack_deploy | jq .default_branch
"centos_new"

What happens when I try to switch back to master via the API?

$ hub api repos/rm-you/devstack_deploy -X PATCH -F default_branch=master
{"message":"Validation Failed","errors":[{"message":"The branch master was not found. Please push that ref first or create it via the Git Data API.","resource":"Repository","field":"default_branch","code":"invalid"}],"documentation_url":"https://developer.github.com/v3/repos/#edit"}

This is clearly broken. Is this the wrong place to be asking about it? Should we file an issue somewhere else?

I can confirm that this API endpoint is indeed malfunctioning. I’m using requests library for Python to do the following:

u = "https://api.github.com/repos/<>/<>"
h =  {'Authorization': 'Token <>'}
requests.patch(u, headers=h, json={'default_branch': 'master'}).json()

This is what I’m getting as a result:

{'message': 'Validation Failed',

'errors': [{'message': 'The branch master was not found. Please push that ref first or create it via the Git Data API.',

   'resource': 'Repository',

   'field': 'default_branch',

   'code': 'invalid'}],

'documentation_url': 'https://developer.github.com/v3/repos/#edit'}

Branch with that name does exist

1 Like

Thanks for taking your time to verify! Appreciate it. That’s enough datapoints that I’m feeling confident it’s not just some weird edge case. :slight_smile:

Adding up to the conversation, I also tried to do this on enterprise and on public but the issue remains the same.

To summarize,

Given:

 - setting the default branch on website is working fine

 - the desired branch is existing

 - in my case, that branch has no protections or any rules that was set

Problem:

 - setting the default branch using API is returning an error

my repo: https://github.com/rhobinjay/git_practice_1

default branch: master

How I did it?

app used to execute the request: Postman

action: PATCH

link: https://api.github.com/repos/rhobinjay/git_practice_1

json data: { “default_branch” : “devel” }

I’d like to add another test case where I executed the api with the same default branch currently setup on the repo. It returned fine and expected but not when I intented to change the default branch to a different one that is existing.

1 Like

Ah, that’s interesting. Yes, I also just verified that if I try to set the existing default branch as the default again, it does work. I literally just did the following (I use the hub utility to run my commands):

  1. Ran the command to check the default branch. Returned: BranchA

  2. Ran the command to change the default branch to BranchB, failed with branch invalid.

  3. Changed the default branch in the UI to BranchB.

  4. Ran the command (from my bash history) to change the default branch to BranchB, which “succeeded”.

Obviously not dealing with a typo or an incorrectly formatted command here, if that works. Great datapoint, thanks @rhobinjay !

Can anyone else see if it’s possible to use API v4 (GraphQL) to do this? While I can get the IDs for all of the branches and I can get the current default branch for a Repository, I can’t find a mutation in the schema that would allow updating a Repository/defaultBranchRef. T_T

I really just need to be able to do this – I’ve got about 50 internal repos to update now (and maybe more in the future) and doing it by hand would technically have been faster at this point given the amount of time I’ve spent on this… Unfortunately, that isn’t really acceptable for a variety of reasons. I’m currently looking at writing something to do it programmatically by parsing GUI HTML with Python / beautifulsoup. I am open to any other suggestions. :frowning:

Hey all, I got the answer to this! I got enough people to look and eventually someone spotted a word I missed in the docs on every read-through: “Required”, up at the top of the repo edit section, on the “name” field.

So, the correct command (including the repo name) is:

hub api repos/rm-you/test_branch_change_api -X PATCH -F name="test_branch_change_api" -F default_branch="new_branch"

Or:

curl -s -H "Authorization: token $GITHUB_TOKEN" https://github.com/api/v3/repos/rm-you/test_branch_change_api -X PATCH --data '{"name": "test_branch_change_api", "default_branch": "new_branch"}'

I don’t totally understand why the repo name is required here, since it is already *necessarily* in the URL Path of the API call… Maybe it’s a verification thing? It also isn’t required in my negative test case for some reason (setting the default to the existing default), probably because of a short-circuit in their logic?

I think there’s still at least one bug here (aforementioned short-circuit), or possibly multiple (the error message is extremely misleading, and there really isn’t a good reason to require the name at all since it is already known), but they aren’t as severe since it *is* possible to do the action.

I’m not sure what the original poster’s issue is now, because I thought it was the same thing but their command DOES include name (I just didn’t because I assumed it was extraneous). So, sorry to the original poster for derailing their post – maybe if they come back we can figure out their issue. :smiley:

But, hopefully this helps other people not struggle as much as I did with this in the future, if they were making the same mistake that I was! :slight_smile:

3 Likes

Thanks rm-you. So weird on my first post, it wasn’t working but now it did. Awesome! knowing that its just a simple fix but tricky. Really appreciate all the efforts to this.

closing…

1 Like

Thanks for the solution, this was driving me crazy. I think they accidentally required the name field as passing a value different than the current repo name renames the repository. It’s not required to match the repository name in the uri path. Interesting find, nice job!