llm
llm copied to clipboard
Encoding Error: `'ascii' codec can't encode character '\xe0' in position 41: ordinal not in range(128)`
Description
When attempting to use the llm command-line interface (CLI) on Windows, I encounter an encoding error related to the ASCII codec. Despite setting environment variables to enforce UTF-8 encoding, the issue persists. Additionally, configuring models results in errors indicating that certain models are unknown or not recognized.
Steps to Reproduce
-
Set Up the Environment:
- Operating System: Windows 10
- PowerShell Version: Name : ConsoleHost Version : 5.1.22621.4111 InstanceId : e0d61ad7-8a35-4d6f-9199-74f95ce5a7e9 UI : System.Management.Automation.Internal.Host.InternalHostUserInterface CurrentCulture : en-US CurrentUICulture : en-GB PrivateData : Microsoft.PowerShell.ConsoleHost+ConsoleColorProxy DebuggerEnabled : True IsRunspacePushed : False Runspace : System.Management.Automation.Runspaces.LocalRunspace
- Python Version: 3.11
- Poetry Version: Poetry (version 1.8.2)
- llm Version: 0.16
-
Configure Environment Variables:
$Env:PYTHONIOENCODING = "utf-8" $Env:PYTHONUTF8 = "1" -
Activate Poetry Virtual Environment:
-
Navigate to a project directory (ensure it's not within
site-packages):mkdir C:\Users\samue\llm-project cd C:\Users\samue\llm-project poetry init --no-interaction poetry add llm poetry shell
-
-
Run the
llmCommand with ASCII Input:llm 'hi'Expected Behavior: The command should execute without encoding errors and return a response from the language model.
Actual Behavior:
Error: 'ascii' codec can't encode character '\xe0' in position 41: ordinal not in range(128) -
Run the
llmCommand with Non-ASCII Input:llm 'Café'Actual Behavior:
Error: 'ascii' codec can't encode character '\xe0' in position 41: ordinal not in range(128) -
Attempt to Add and Set a Model:
llm models add groq-llama3.1-70b --path "C:\Path\To\groq-llama3.1-70b" llm models set default groq-llama3.1-70bActual Behavior:
Error: Unknown model: groq-llama3.1-70b -
List Available Models:
llm models listActual Output:
Available models: - groq-llama3.1-70b -
Attempt to Use the Default Model:
llm 'hi'Actual Behavior:
Error: 'groq-llama3.1-70b' is not a known model
Expected Behavior
- The
llmcommand should handle both ASCII and non-ASCII inputs without encountering encoding errors. - Adding and setting models should recognize and configure valid models without errors.
Actual Behavior
-
Encountering an encoding error when using non-ASCII characters, specifically:
Error: 'ascii' codec can't encode character '\xe0' in position 41: ordinal not in range(128) -
Errors related to unrecognized models when attempting to add or set a default model:
Error: 'groq-llama3.1-70b' is not a known model
Environment
- Operating System: Windows 10
- PowerShell Version: [ Name : ConsoleHost Version : 5.1.22621.4111 InstanceId : e0d61ad7-8a35-4d6f-9199-74f95ce5a7e9 UI : System.Management.Automation.Internal.Host.InternalHostUserInterface CurrentCulture : en-US CurrentUICulture : en-GB PrivateData : Microsoft.PowerShell.ConsoleHost+ConsoleColorProxy DebuggerEnabled : True IsRunspacePushed : False Runspace : System.Management.Automation.Runspaces.LocalRunspace]
- Python Version: 3.11
- Poetry Version: [Please provide the output of
poetry --version] - llm Version: 0.16
- Installation Path:
C:\Users\samue\AppData\Roaming\pypoetry\venv\Lib\site-packages\llm\ - Virtual Environment Path:
C:\Users\samue\AppData\Roaming\pypoetry\venv\Lib\site-packages\llm\llm-test\.venv
Environment Variables
$Env:PYTHONIOENCODING = "utf-8"
$Env:PYTHONUTF8 = "1"
Additional Context
-
Attempted Solutions:
- Set PowerShell's output encoding to UTF-8.
- Configured Python environment variables (
PYTHONIOENCODINGandPYTHONUTF8) to enforce UTF-8 encoding. - Activated the Poetry virtual environment within a separate project directory.
- Tried adding and setting different models, including a local model (
groq-llama3.1-70b), which resulted in errors.
-
Error Messages:
Error: 'ascii' codec can't encode character '\xe0' in position 41: ordinal not in range(128)Error: 'groq-llama3.1-70b' is not a known model -
Commands Run:
llm 'hi' llm 'Café' llm models add groq-llama3.1-70b --path "C:\Path\To\groq-llama3.1-70b" llm models set default groq-llama3.1-70b llm models list llm 'hi' -
Attempts to Use
llm-cmd:llm-cmd hiResult:
llm-cmd : The term 'llm-cmd' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again. -
Notes:
- Attempting to run
poetry shellwithin thesite-packages\llmdirectory results in an error due to the absence of apyproject.tomlfile. - The issue persists even after setting environment variables within the Poetry shell.
- Attempting to run
llm -m claude-3-5-sonnet-latest --key llm-claude-3 'Hello'
Error: 'ascii' codec can't encode character '\u221a' in position 0: ordinal not in range(128)
facing the same issue, running aarch macOS, iterm2, zsh
Similar issue on aarch_64 MacOS, default terminal, zsh, Starship prompter
$ llm -m claude-3.5-sonnet 'Fun facts about pelicans'
Error: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
I wonder if this is some kind of terminal configuration thing? Like maybe I've never seen this because my terminal is happy displaying UTF-8?
I just tried it in windows cmd.exe and "Powershell" 🤔 but I get the same error.
Here's a full traceback:
PS C:\Users\Docker> llm chat
Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "C:\Users\Docker\.local\bin\llm.exe\__main__.py", line 7, in <module>
File "C:\Users\Docker\pipx\venvs\llm\lib\python3.12\site-packages\click\core.py", line 1161, in __call__
return self.main(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\llm\lib\python3.12\site-packages\click\core.py", line 1082, in main
rv = self.invoke(ctx)
^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\llm\lib\python3.12\site-packages\click\core.py", line 1697, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\llm\lib\python3.12\site-packages\click\core.py", line 1443, in invoke
return ctx.invoke(self.callback, **ctx.params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\llm\lib\python3.12\site-packages\click\core.py", line 788, in invoke
return __callback(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\llm\lib\python3.12\site-packages\llm\cli.py", line 875, in chat
model = get_model(model_id)
^^^^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\llm\lib\python3.12\site-packages\llm\__init__.py", line 240, in get_model
aliases = get_model_aliases()
^^^^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\llm\lib\python3.12\site-packages\llm\__init__.py", line 195, in get_model_aliases
for model_with_aliases in get_models_with_aliases():
^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\llm\lib\python3.12\site-packages\llm\__init__.py", line 97, in get_models_with_aliases
pm.hook.register_models(register=register)
File "C:\Users\Docker\pipx\venvs\llm\lib\python3.12\site-packages\pluggy\_hooks.py", line 513, in __call__
return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\llm\lib\python3.12\site-packages\pluggy\_manager.py", line 120, in _hookexec
return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\llm\lib\python3.12\site-packages\pluggy\_callers.py", line 139, in _multicall
raise exception.with_traceback(exception.__traceback__)
File "C:\Users\Docker\pipx\venvs\llm\lib\python3.12\site-packages\pluggy\_callers.py", line 103, in _multicall
res = hook_impl.function(*args)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\llm\lib\python3.12\site-packages\llm_groq.py", line 24, in register_models
models = get_model_details()
^^^^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\llm\lib\python3.12\site-packages\llm_groq.py", line 66, in get_model_details
return refresh_models()
^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\llm\lib\python3.12\site-packages\llm_groq.py", line 47, in refresh_models
response = httpx.get(
^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\llm\lib\python3.12\site-packages\httpx\_api.py", line 195, in get
return request(
^^^^^^^^
File "C:\Users\Docker\pipx\venvs\llm\lib\python3.12\site-packages\httpx\_api.py", line 109, in request
return client.request(
^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\llm\lib\python3.12\site-packages\httpx\_client.py", line 812, in request
request = self.build_request(
^^^^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\llm\lib\python3.12\site-packages\httpx\_client.py", line 367, in build_request
headers = self._merge_headers(headers)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\llm\lib\python3.12\site-packages\httpx\_client.py", line 430, in _merge_headers
merged_headers.update(headers)
File "C:\Users\Docker\pipx\venvs\llm\lib\python3.12\site-packages\httpx\_models.py", line 275, in update
headers = Headers(headers)
^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\llm\lib\python3.12\site-packages\httpx\_models.py", line 156, in __init__
bytes_value = _normalize_header_value(v, encoding)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\llm\lib\python3.12\site-packages\httpx\_models.py", line 82, in _normalize_header_value
return value.encode(encoding or "ascii")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
UnicodeEncodeError: 'ascii' codec can't encode character '\xe0' in position 7: ordinal not in range(128)
Here's another instance of the same error, now from cmd.exe (I get to see the first prompt ">")
C:\Users\Docker\pipx\venvs\gtk-llm-chat\bin>python -m llm chat -c
Chatting with openrouter/meta-llama/llama-3-8b-instruct
Type 'exit' or 'quit' to exit
Type '!multi' to enter multiple lines, then '!end' to finish
> hola!
Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "C:\Users\Docker\pipx\venvs\gtk-llm-chat\lib\python3.12\site-packages\llm\__main__.py", line 4, in <module>
cli()
File "C:\Users\Docker\pipx\venvs\gtk-llm-chat\lib\python3.12\site-packages\click\core.py", line 1161, in __call__
return self.main(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\gtk-llm-chat\lib\python3.12\site-packages\click\core.py", line 1082, in main
rv = self.invoke(ctx)
^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\gtk-llm-chat\lib\python3.12\site-packages\click\core.py", line 1697, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\gtk-llm-chat\lib\python3.12\site-packages\click\core.py", line 1443, in invoke
return ctx.invoke(self.callback, **ctx.params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\gtk-llm-chat\lib\python3.12\site-packages\click\core.py", line 788, in invoke
return __callback(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\gtk-llm-chat\lib\python3.12\site-packages\llm\cli.py", line 940, in chat
for chunk in response:
^^^^^^^^
File "C:\Users\Docker\pipx\venvs\gtk-llm-chat\lib\python3.12\site-packages\llm\models.py", line 563, in __iter__
for chunk in self.model.execute(
^^^^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\gtk-llm-chat\lib\python3.12\site-packages\llm\default_plugins\openai_models.py", line 581, in execute
completion = client.chat.completions.create(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\gtk-llm-chat\lib\python3.12\site-packages\openai\_utils\_utils.py", line 287, in wrapper
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\gtk-llm-chat\lib\python3.12\site-packages\openai\resources\chat\completions\completions.py", line 925, in create
return self._post(
^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\gtk-llm-chat\lib\python3.12\site-packages\openai\_base_client.py", line 1239, in post
return cast(ResponseT, self.request(cast_to, opts, stream=stream, stream_cls=stream_cls))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\gtk-llm-chat\lib\python3.12\site-packages\openai\_base_client.py", line 958, in request
request = self._build_request(options, retries_taken=retries_taken)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\gtk-llm-chat\lib\python3.12\site-packages\openai\_base_client.py", line 495, in _build_request
headers = self._build_headers(options, retries_taken=retries_taken)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\gtk-llm-chat\lib\python3.12\site-packages\openai\_base_client.py", line 439, in _build_headers
headers = httpx.Headers(headers_dict)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\gtk-llm-chat\lib\python3.12\site-packages\httpx\_models.py", line 156, in __init__
bytes_value = _normalize_header_value(v, encoding)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\gtk-llm-chat\lib\python3.12\site-packages\httpx\_models.py", line 82, in _normalize_header_value
return value.encode(encoding or "ascii")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
UnicodeEncodeError: 'ascii' codec can't encode character '\xe0' in position 7: ordinal not in range(128)
This appears to recreate the bug (or a similar problem) on my Mac:
PYTHONIOENCODING=ascii llm 'say hi in Japanese'
Output:
Hi in Japanese is Error: 'ascii' codec can't encode characters in position 0-4: ordinal not in range(128)
Not convinced that it's happening at the same time. It happens to me without non-ascii characters.
Trying it on Gemini 2.5 Pro:
llm -m gemini-2.5-pro-preview-03-25 \
-f github:simonw/llm \
-f issue:https://github.com/simonw/llm/issues/576 \
-s 'Brainstorm ideas for fixing this bug, I am stuck'
58.0958 cents and not a very useful response - it's very keen on investigating httpx: https://gist.github.com/simonw/14939ea164ed5e9541ff74bac9091278#response
Huh I just noticed this from an earlier traceback:
File "C:\Users\Docker\pipx\venvs\llm\lib\python3.12\site-packages\llm_groq.py", line 24, in register_models
models = get_model_details()
^^^^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\llm\lib\python3.12\site-packages\llm_groq.py", line 66, in get_model_details
return refresh_models()
^^^^^^^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\llm\lib\python3.12\site-packages\llm_groq.py", line 47, in refresh_models
response = httpx.get(
^^^^^^^^^^
File "C:\Users\Docker\pipx\venvs\llm\lib\python3.12\site-packages\httpx\_api.py", line 195, in get
Here's refresh_models() in llm_groq: https://github.com/angerman/llm-groq/blob/f7335e34db4bce9784bb010ca6e773e4f317b59c/llm_groq.py#L39-L54
response = httpx.get(
MODEL_ENDPOINT,
headers={"Authorization": f"Bearer {key}"},
)
response.raise_for_status()
MODEL_ENDPOINT is:
https://api.groq.com/openai/v1/models
Any change that Groq API key has odd characters in it? Seems unlikely, mine is gsk_ and then a sequence of a-zA-Z0-9.
This is interesting:
curl -i 'https://api.groq.com/openai/v1/models' -H "Authorization: Bearer $(llm keys get groq)"
Response:
HTTP/2 200
date: Wed, 23 Apr 2025 22:44:39 GMT
content-type: application/json
cf-ray: 9350e2ff9d337d7c-LAX
cf-cache-status: DYNAMIC
cache-control: private, max-age=0, no-store, no-cache, must-revalidate
vary: Origin
via: 1.1 google
alt-svc: h3=":443"; ma=86400
x-groq-region: us-west-1
x-request-id: req_01jsjd66zfe0atprgvpe5p278b
set-cookie: __cf_bm=eH4OyLMTYPStybsphIs5ZNPEWNSB5EEex6egU4rG9VM-1745448279-1.0.1.1-CKhzfauZiw29jjk3A7uk7M_ed7TMsEb2swsVkavGwBOxigpbAhpDDIz1gscxmfLt1we2Xe00qkYJqeGGyiyN6AkfV3S5O6DZHu5r1N04Vwg; path=/; expires=Wed, 23-Apr-25 23:14:39 GMT; domain=.groq.com; HttpOnly; Secure; SameSite=None
server: cloudflare
{"object":"list","data":[{"id":"compound-beta-mini","object":"model","created":1742953279,"owned_by":"Groq","active":true,"context_window":8192,"public_apps":null,"max_completion_tokens":8192},{"id":"playai-tts","object":"model","created":1740682771,"owned_by":"PlayAI","active":true,"context_window":8192,"public_apps":null,"max_completion_tokens":8192},{"id":"llama3-8b-8192","object":"model","created":1693721698,"owned_by":"Meta","active":true,"context_window":8192,"public_apps":null,"max_completion_tokens":8192},{"id":"whisper-large-v3-turbo","object":"model","created":1728413088,"owned_by":"OpenAI","active":true,"context_window":448,"public_apps":null,"max_completion_tokens":448},{"id":"llama-guard-3-8b","object":"model","created":1693721698,"owned_by":"Meta","active":true,"context_window":8192,"public_apps":null,"max_completion_tokens":8192},{"id":"deepseek-r1-distill-llama-70b","object":"model","created":1737924940,"owned_by":"DeepSeek / Meta","active":true,"context_window":131072,"public_apps":null,"max_completion_tokens":131072},{"id":"qwen-qwq-32b","object":"model","created":1741214760,"owned_by":"Alibaba Cloud","active":true,"context_window":131072,"public_apps":null,"max_completion_tokens":131072},{"id":"llama-3.1-8b-instant","object":"model","created":1693721698,"owned_by":"Meta","active":true,"context_window":131072,"public_apps":null,"max_completion_tokens":131072},{"id":"distil-whisper-large-v3-en","object":"model","created":1693721698,"owned_by":"Hugging Face","active":true,"context_window":448,"public_apps":null,"max_completion_tokens":448},{"id":"whisper-large-v3","object":"model","created":1693721698,"owned_by":"OpenAI","active":true,"context_window":448,"public_apps":null,"max_completion_tokens":448},{"id":"gemma2-9b-it","object":"model","created":1693721698,"owned_by":"Google","active":true,"context_window":8192,"public_apps":null,"max_completion_tokens":8192},{"id":"mistral-saba-24b","object":"model","created":1739996492,"owned_by":"Mistral AI","active":true,"context_window":32768,"public_apps":null,"max_completion_tokens":32768},{"id":"allam-2-7b","object":"model","created":1737672203,"owned_by":"SDAIA","active":true,"context_window":4096,"public_apps":null,"max_completion_tokens":4096},{"id":"playai-tts-arabic","object":"model","created":1740682783,"owned_by":"PlayAI","active":true,"context_window":8192,"public_apps":null,"max_completion_tokens":8192},{"id":"llama3-70b-8192","object":"model","created":1693721698,"owned_by":"Meta","active":true,"context_window":8192,"public_apps":null,"max_completion_tokens":8192},{"id":"compound-beta","object":"model","created":1740880017,"owned_by":"Groq","active":true,"context_window":8192,"public_apps":null,"max_completion_tokens":8192},{"id":"llama-3.3-70b-versatile","object":"model","created":1733447754,"owned_by":"Meta","active":true,"context_window":131072,"public_apps":null,"max_completion_tokens":32768},{"id":"meta-llama/llama-4-maverick-17b-128e-instruct","object":"model","created":1743877158,"owned_by":"Meta","active":true,"context_window":131072,"public_apps":null,"max_completion_tokens":8192},{"id":"meta-llama/llama-4-scout-17b-16e-instruct","object":"model","created":1743874824,"owned_by":"Meta","active":true,"context_window":131072,"public_apps":null,"max_completion_tokens":8192}]}
Note that content-type: application/json doesn't specify the character encoding.
But I'm pretty sure that JSON that came back is entirely ASCII characters anyway.
You're onto something!
In the windows terminal when I pasted the API key, it seems to have stored it with non-ascii chars, I'm guessing as an artifact of using a VM. Having cleaned up my keys.json file - and making sure to add proper ascii for the api key in keys.json made it work!
Perhaps let's make sure that no non-ascii chars can ever get into keys.json vía the llm command.
I faced the same problem, but in my case the solution wasn't cleaning up keys.json. I had to set PowerShell's output encoding to UTF-8:
$OutputEncoding = [Console]::OutputEncoding = [Text.UTF8Encoding]::UTF8
This resolved the codec error for me on Windows.