When I try to run command like cci service connect github or cci org scratch dev <alias> --default I've received error

'utf-8' codec can't decode byte 0x80 in position 0: invalid start byte

I am working on Windows with Windows Subsystem for Linux (WSL).

  • CumulusCI version: 3.44.1
  • Python version: 3.8.10

sfdx-cli and cumulusci are installed of course. Weird error, because on CumulusCI 3.43.0 and Python 3.8.10 one mate has the same issue, and second not. Maybe someone has met that issue? cumulusci.yml is in UTF-8 encoding. After run cci error gist I received same error. But on cci error info I received:

Traceback (most recent call last):
  File "/home/mizio/.local/pipx/venvs/cumulusci/lib/python3.8/site-packages/cumulusci/cli/cci.py", line 76, in main
    cli(args[1:], standalone_mode=False, obj=runtime)
  File "/home/mizio/.local/pipx/venvs/cumulusci/lib/python3.8/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/home/mizio/.local/pipx/venvs/cumulusci/lib/python3.8/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/home/mizio/.local/pipx/venvs/cumulusci/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/mizio/.local/pipx/venvs/cumulusci/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/mizio/.local/pipx/venvs/cumulusci/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/mizio/.local/pipx/venvs/cumulusci/lib/python3.8/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/home/mizio/.local/pipx/venvs/cumulusci/lib/python3.8/site-packages/click/decorators.py", line 21, in new_func
    return f(get_current_context(), *args, **kwargs)
  File "/home/mizio/.local/pipx/venvs/cumulusci/lib/python3.8/site-packages/cumulusci/cli/runtime.py", line 182, in new_func
  File "/home/mizio/.local/pipx/venvs/cumulusci/lib/python3.8/site-packages/cumulusci/core/runtime.py", line 88, in _load_keychain
    self.keychain = self.keychain_cls(self.project_config, keychain_key)
  File "/home/mizio/.local/pipx/venvs/cumulusci/lib/python3.8/site-packages/cumulusci/core/keychain/base_project_keychain.py", line 39, in __init__
  File "/home/mizio/.local/pipx/venvs/cumulusci/lib/python3.8/site-packages/cumulusci/core/keychain/base_project_keychain.py", line 45, in _load_keychain
  File "/home/mizio/.local/pipx/venvs/cumulusci/lib/python3.8/site-packages/cumulusci/core/keychain/encrypted_file_project_keychain.py", line 531, in _load_services
  File "/home/mizio/.local/pipx/venvs/cumulusci/lib/python3.8/site-packages/cumulusci/core/keychain/encrypted_file_project_keychain.py", line 651, in _load_service_files
    config = f.read()
  File "/usr/lib/python3.8/codecs.py", line 322, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 0: invalid start byte
  • Did you solved this issue? I'm facing it 1 year after this post and there isn't much info about this on Google.
    – Saulo
    Nov 4, 2022 at 11:06

1 Answer 1


WSL is not officially supported for CumulusCI, but I managed to find a way to fix the issue, shown in the steps below, it could be a workaround until Salesforce.org fixes this issue on WSL.

  1. Create a person access token with gist and repo scopes

  2. Empty the content of the cumulus CI github service file with .service extension under ~/.cumulusci/services/github, empty the content in this file. Keep this empty file, but DON’T DELETE IT. enter image description here

  3. Find a python file called “encrypted_file_project_keychain.py” in your CumulusCI installation folder, in my case, python version 3.10.6, CumulusCI version 3.72.1, it is “~/.local/pipx/venvs/cumulusci/lib/python3.10/site-packages/cumulusci/core/keychain/encrypted_file_project_keychain.py”.

  4. Identify the method: “def _load_service_files(self) -> None:” in “encrypted_file_project_keychain.py”, and add the code snippet into it after statement “service_type = item.parent.name”, Please note: Replace $GITHUB_USERNAME, $GITHUB_EMAIL, $GITHUB_TOKEN with your username, email and person access token.

             if service_type == 'github':
                # print(config)
                config = ServiceConfig(
                    {'service_name': 'mygithub', 'username': $GITHUB_USERNAME, 'email': $GITHUB_EMAIL, 'token': $GITHUB_TOKEN, 'Organizations': '', 'scopes': 'gist, repo'}
  5. The method should look like the one below

    def _load_service_files(self) -> None:

     services_dir = Path(f"{self.global_config_dir}/services")
     for item in services_dir.glob("**/*"):
         if item.suffix == ".service":
             with open(item) as f:
                 config = f.read()
             name = item.name.replace(".service", "")
             service_type = item.parent.name
             if service_type == 'github':
                 # print(config)
                 config = ServiceConfig(
                     {'service_name': 'mygithub', 'username': $GITHUB_USERNAME, 'email': $GITHUB_EMAIL, 'token': $GITHUB_TOKEN, 'Organizations': '', 'scopes': 'gist, repo'}
                 service_type, name, config, save=False, config_encrypted=True
  6. you can test it by running “cci service list”, and you should be able to see something similar below. Your GitHub account is now connected and the error disappears.

enter image description here

  • 1
    I get the feeling that the downvotes here are because of the link to your blog which you did not disclose your affiliation to. I'm giving this one a pass because it does appear that the answer is relevant and the important details are reproduced here (i.e. the blog post contains supplemental information that wouldn't fit well in the SE Q&A format).
    – Derek F
    Feb 17 at 13:58
  • Same. Important details are provided here. The link is honestly easy to miss altogether, and the answer still provides value without clicking on it. Clearing spam flags.
    – Adrian Larson
    Feb 17 at 16:01
  • Thanks Derek and Adrian for your information, I am new here, and lesson leant for me. I have updated the answer and removed the link, and hopefully this can help people solve this issue on WSL for now.
    – Jun Liu
    Feb 17 at 20:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .