Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics

[Now with Workaround] Several different unexplained ways that butler is failing in GitLab CI

A topic by atiaxi created Nov 16, 2021 Views: 945 Replies: 9
Viewing posts 1 to 9
(1 edit) (+1)

Welcome, all, to the rabbit hole that has been me trying to get butler to work even a little bit on gitlab CI.

Here's the relevant bits of my CI file:

  stage: deploy
  image: dosowisko/butler
  when: manual
    - mkdir -p ~/.config/itch
    - echo ${BUTLER_API_KEY} > ~/.config/itch/butler_creds
    - butler login
    - butler push ./build/unstable atiaxi/tyranny-of-the-labyrinth:web --userversion-file ./VERSION.txt --verbose

Now, if you've seen any other "how to deploy using butler on gitlab CI" tutorials, you may be wondering what the deal with `butler login` is up there, because none of them have it.  The deal is, without it I get this error:

$ butler push build/unstable atiaxi/tyranny-of-the-labyrinth:web --userversion-file ./VERSION.txt
creating build on remote server: Post "<a href=""></a>": http: ContentLength=71 with Body length 0
Cleaning up project directory and file based variables00:01
ERROR: Job failed: exit code 1

Note that is not a "you have bad credentials" error (that would have given a useful error message, as I verified by deliberately mangling the credentials), it's just some bizarre error that doesn't explain itself and diving into the source told me nothing.  I can provide a verbose version of this error if needed, but it contains no useful additional information (the traceback just points to the `.Post` calls, as you'd expect).

So, I added the bit where it puts the API key where butler expects to find it, and then it logs in.  And that worked!  Exactly once.

When I revoked that key (because, in my debugging, I'd resorted to straight-up just printing the stupid thing out) and tried a new one, it failed again.  Did it fail with a reasonable error message?  Well, this post isn't titled "several different reasonably-explained ways that butler is failing" so no.  Instead, this!

$ butler login
validating credentials: Get "<a href=""></a>": context deadline exceeded

Google tells me that the answer to this error is "get better internet lul" which doesn't help much.  Fortunately those answers are old, because since the time they were posted butler added a handy command line flag to actually tell it to wait longer!  Useful...

$ butler login --context-timeout=120
validating credentials: http: read on closed response body

unless of course it's the server that's decided to (presumably) time out for - wait for it - unexplained reasons!

So after spending a solid several hours on and off throughout the day trying to get this to work, I'm officially throwing in the towel and asking here.  Is there anything I haven't tried that I should be trying, or things I have tried that I shouldn't?  What on earth is happening here?  Why does every other butler problem on the entire internet that I've googled have reasonable error messages except for this specific one that's afflicting me?  Why am I so hungry and tired?

Actually, I'll take care of that last one right now, I think.  Thanks for reading through this half problem half rant of a post.

(Incidentally, of course, all of this works entirely flawlessly on windows, because linux hates me today I guess).


(Still failing, but more info)

Just in case the culprit was the docker image, I changed my CI file to get butler itself and run that:

  stage: deploy
  when: manual
    - mkdir -p ~/.config/itch
    - echo ${BUTLER_API_KEY} > ~/.config/itch/butler_creds
    - curl -L -o
    - unzip
    - chmod +x butler
    - ./butler -V
    - ./butler login
    - ./butler push ./build/unstable atiaxi/tyranny-of-the-labyrinth:web --userversion-file ./VERSION.txt --verbose

The result of `./butler -v` was:

v15.21.0, built on May 11 2021 @ 18:18:40, ref 6ad656eebbb5b80bf2065644d8bf9e40a15e8276

And I get the same errors (context exceeded for the login, unexplained if I skip login and just try push).


Here's a minimal repo to reproduce the problem:

Admin (3 edits)

butler login is going to be an interactive prompt to allow you to log in via your browser. This is not something that is going to work on your CI runner which is running completely headless. See the instructions here:

Can you confirm that whatever is written in .config/itch/butler_creds is a valid API key for the account/project being pushed?

Running the same script locally may help you identify where the issue is located.


Hi Leafo, thanks for reading through all that :)

Interestingly enough, butler login did work... that one time.  It hasn't worked since, so most of my latest experiments have been tried without it.  I still get the "ContentLength=71 with Body length 0" error.

As far as I can tell, the butler_creds file has a valid API key.  I unmasked it and put a `cat` line in there and it looked identical to the one I have on my local machine.  I copied it to my local machine and verified it was working.  Then I revoked it and got a new one because that project's visible to the whole world :)

Everything works perfectly fine on my local windows machine.  Using an invalid key here gives me an invalid key error, so whatever the problem is remotely, it's (probably) not that.

(1 edit)

I am getting the exact same issue, I tried lots of things but no luck. I am building a Godot game so I am using baricello's Godot 3.4 docker image. Worth mentioning that I used his image from 3.3.2 on another project and that did not fail when I used it some time ago, but I re-tried that project today (with image 3.3.2 too) and failed with the same mysterious error. Tried to use -v flag to output info but nothing useful outputs (mostly directories, no real error message)


Okay so after trying literally everything I could imagine of, I think I finally fixed it, by using my own Gitlab Runner:
- I installed Docker Desktop on my laptop
- I followed the instructions on Gitlab about installing your own Gitlab Runner with Docker and registered my Gitlab Runner
- In the project settings I disabled using shared runners and set it so pipelines only run using my runner
- Tried to execute the pipeline and butler push didn't fail.

So it might be a temporary Gitlab issue? I don't know, I do still have to test it on a few more pipelines I have but seems promising

I am seeing this issue as well, using baricello’s godot docker image as well. Rather than set up my own gitlab-runner, I’ve switched to Jenkins-ci until a solution is found for gitlab

As an update, I was able to recreate what everyone else in the thread is saying:  On a separate (non-shared) runner, everything works fine.  So the workaround for the issue is to set up your own runner.  Upsides are that it's actually pretty easy and quite a bit faster than shared runners, downsides are that you have to have a spare machine somewhere to put the runner on.

I've sent this info to the GitLab runner team, but since it seems to be butler-specific (downloading butler works fine, connectivity to works fine) there's probably not going to be a fix coming anytime soon unless someone's really willing to dive into it.

I'll update the thread if anything changes; thanks again to everyone for reading this and the advice!


echo ${BUTLER_API_KEY} > ~/.config/itch/butler_creds

By default, echo appends a newline to the output. butler for whatever reason includes the newline as part of the API key when it reads the credential file, which of course is an incorrect key.

I added the -n flag to the echo command (and removed the butler login line) and my project was uploaded successfully.

  - mkdir -p ~/.config/itch
  - echo -n "${BUTLER_API_KEY}" > ~/.config/itch/butler_creds
  - butler push ...