does any one was able to run mix test with codex.
Yes, installing hex is working with mix archive.install github hexpm/hex branch latest --force, itās rebar thatās giving me troubles.
Installing deps from github is working, but installing deps from hex.pm or cdn.jsdelivr.net is not. I guess they have to whitelist these domains first.
Hey all, just checking in, is codex working okay for you at this point? Have you found any gotchas? I originally tried to use the hex mirror and found some dependencies didnāt work. Has this been your experience?
I would really like to use it if possible!
I ended up going back to the (locally used) Claude Code. The hex mirror is too unstable, and while the codexās promise is good, I will wait till they improve their infrastructure.
Ahh, okay thanks for the update. I hope itās working soon.
Iām using the gist posted in this thread and it does work - sometimes. When it fails, I restart the task. Sometimes it takes a few restarts before it succeeds. But it does succeed eventually.
Annoying, but codex is free for now so Iād rather use it than other options.
Sometimes it takes a few restarts before it succeeds.
Honestly, I feel like itās worse than before? I just restarted a task five times last night, three times now⦠Without success.
I donāt know if the problem is on OpenAIās side or Hexās, but itās really frustrating. Especially when you see the boost that Codex represents on non-Elixir projectsā¦
Curious, has anyone tried hosting their own private mirror of hex? Wondering if thatās a viable option.
Can you show the 403 errors. Afaict we donāt respond with 403 errors from repo.hex.pm unless you are doing authenticated requests for private packages.
I have tried the script provided by @vkryukov but I get the same error when using jsDeliver and no mirror. Can someone show the errors they are getting when using repo.hex.pm directly?
I asked our engineer Savvas to look into this. He is still working on it and will post more details later. But here the brief explanation of what is broken and how to work around it.
- httpc library used by Hex has a bug which makes it fail with proxy server that Codex uses. Savvas filed a bug here: httpc violates RFC 2616 for default requests Ā· Issue #10065 Ā· erlang/otp Ā· GitHub
- Hex can be patched to work around the httpc bug: Comparing hexpm:latest...650health:latest Ā· hexpm/hex Ā· GitHub
- Various Elixir/Erlang utilities need to be configured to use the proxy and its CA certificate
Here is the setup script that should work for now:
# OpenAI Codex setup script for Elixir projects
go install github.com/asdf-vm/asdf/cmd/asdf@v0.18.0
asdf plugin add erlang https://github.com/michallepicki/asdf-erlang-prebuilt-ubuntu-24.04.git || true
asdf plugin add elixir
asdf install erlang 28.0.2
asdf set --home erlang 28.0.2
asdf install elixir 1.18.4-otp-28
asdf set --home elixir 1.18.4-otp-28
echo 'export PATH=$HOME/.asdf/shims:$PATH' >> ~/.bashrc
echo 'export HEX_CACERTS_PATH=$CODEX_PROXY_CERT' >> ~/.bashrc
export PATH=$HOME/.asdf/shims:$PATH
export HEX_CACERTS_PATH=$CODEX_PROXY_CERT
# use hex fork with a workaround for httpc bug https://github.com/erlang/otp/issues/10065
mix archive.install --force github 650health/hex branch latest
# mix local.rebar doesn't work on Codex likely because it's not respecting HEX_CACERTS_PATH env var.
# TODO investigate this further
# install rebar manually as a temporary workaround
curl -L -o rebar3 https://s3.amazonaws.com/rebar3/rebar3
chmod +x ./rebar3
./rebar3 local install
export PATH=/root/.cache/rebar3/bin:$PATH
mix local.rebar rebar3 $(which rebar3)
mix deps.get
mix deps.compile
mix compile
Since mise is already used in codex and it supports asdf plugins it can be used instead
# make sure mise + its shims are on PATH now and later
echo 'export PATH=$HOME/.local/bin:$PATH' >> ~/.bashrc
echo 'export PATH=$HOME/.local/share/mise/shims:$PATH' >> ~/.bashrc
echo 'export HEX_CACERTS_PATH=$CODEX_PROXY_CERT' >> ~/.bashrc
export PATH=$HOME/.local/bin:$PATH
export PATH=$HOME/.local/share/mise/shims:$PATH
export HEX_CACERTS_PATH=$CODEX_PROXY_CERT
# plugins (mise can use asdf-style plugins)
mise plugins install erlang https://github.com/michallepicki/asdf-erlang-prebuilt-ubuntu-24.04.git || true
mise plugins install elixir https://github.com/mise-plugins/mise-elixir.git
# tool installs + set as global (equivalent to asdf --home)
mise install erlang@28.0.2
mise use --global erlang@28.0.2
mise install elixir@1.18.4-otp-28
mise use --global elixir@1.18.4-otp-28
# use hex fork with a workaround for httpc bug https://github.com/erlang/otp/issues/10065
mix archive.install --force github 650health/hex branch latest
# mix local.rebar doesn't work on Codex likely because it's not respecting HEX_CACERTS_PATH env var.
# TODO investigate this further
# install rebar manually as a temporary workaround
curl -L -o rebar3 https://s3.amazonaws.com/rebar3/rebar3
chmod +x ./rebar3
./rebar3 local install
export PATH=/root/.cache/rebar3/bin:$PATH
mix local.rebar rebar3 "$(which rebar3)"
mix deps.get
mix compile
I struggled a bit to get a Phoenix + Ash project running tests inside OpenAIās Codex environment, but I found a setup that works reliably. Several steps run in parallel to keep it fast.
Gist: elixir-phoenix-ash-codex-setup.sh Ā· GitHub
Pay attention: You will need to change "app_dev"
Iāll be really happy to improve it based on your feedback
Has anyone successfully used codex with rustler?
For example, Iām using mdex and am having issues with the http proxy reaching out to github. I think I could precompile the dependencies though Iād prefer not to change my application configuration just for codex.
Iāve verified the same issue with other rustler dependencies as well.
==> mdex
Compiling 3 files (.ex)
12:29:02.476 [debug] Downloading NIF from https://github.com/leandrocp/mdex/releases/download/v0.1.14/libcomrak_nif-v0.1.14-nif-2.15-x86_64-unknown-linux-gnu.so.tar.gz
12:29:02.476 [debug] Using HTTP_PROXY: http://proxy:8080
12:29:02.476 [debug] Using HTTPS_PROXY: http://proxy:8080
12:29:02.617 [info] Attempt 1 failed with {:error, "couldn't fetch NIF from https://github.com/leandrocp/mdex/releases/download/v0.1.14/libcomrak_nif-v0.1.14-nif-2.15-x86_64-unknown-linux-gnu.so.tar.gz: {:ok, {{~c\"HTTP/1.1\", 503, ~c\"Service Unavailable\"}, [{~c\"date\", ~c\"Mon, 08 Sep 2025 12:29:02 GMT\"}, {~c\"server\", ~c\"envoy\"}, {~c\"content-length\", ~c\"85\"}, {~c\"content-type\", ~c\"text/plain\"}], \"upstream connect error or disconnect/reset before headers. reset reason: remote reset\"}}"}
12:29:04.558 [debug] Downloading NIF from https://github.com/leandrocp/mdex/releases/download/v0.1.14/libcomrak_nif-v0.1.14-nif-2.15-x86_64-unknown-linux-gnu.so.tar.gz
12:29:04.558 [debug] Using HTTP_PROXY: http://proxy:8080
12:29:04.558 [debug] Using HTTPS_PROXY: http://proxy:8080
12:29:04.693 [info] Attempt 2 failed with {:error, "couldn't fetch NIF from https://github.com/leandrocp/mdex/releases/download/v0.1.14/libcomrak_nif-v0.1.14-nif-2.15-x86_64-unknown-linux-gnu.so.tar.gz: {:ok, {{~c\"HTTP/1.1\", 503, ~c\"Service Unavailable\"}, [{~c\"date\", ~c\"Mon, 08 Sep 2025 12:29:04 GMT\"}, {~c\"server\", ~c\"envoy\"}, {~c\"content-length\", ~c\"85\"}, {~c\"content-type\", ~c\"text/plain\"}], \"upstream connect error or disconnect/reset before headers. reset reason: remote reset\"}}"}
12:29:07.951 [debug] Downloading NIF from https://github.com/leandrocp/mdex/releases/download/v0.1.14/libcomrak_nif-v0.1.14-nif-2.15-x86_64-unknown-linux-gnu.so.tar.gz
12:29:07.951 [debug] Using HTTP_PROXY: http://proxy:8080
12:29:07.951 [debug] Using HTTPS_PROXY: http://proxy:8080
12:29:08.030 [info] Attempt 3 failed with {:error, "couldn't fetch NIF from https://github.com/leandrocp/mdex/releases/download/v0.1.14/libcomrak_nif-v0.1.14-nif-2.15-x86_64-unknown-linux-gnu.so.tar.gz: {:ok, {{~c\"HTTP/1.1\", 503, ~c\"Service Unavailable\"}, [{~c\"date\", ~c\"Mon, 08 Sep 2025 12:29:07 GMT\"}, {~c\"server\", ~c\"envoy\"}, {~c\"content-length\", ~c\"85\"}, {~c\"content-type\", ~c\"text/plain\"}], \"upstream connect error or disconnect/reset before headers. reset reason: remote reset\"}}"}
Compiling lib/mdex/native.ex (it's taking more than 10s)
12:29:12.743 [debug] Downloading NIF from https://github.com/leandrocp/mdex/releases/download/v0.1.14/libcomrak_nif-v0.1.14-nif-2.15-x86_64-unknown-linux-gnu.so.tar.gz
12:29:12.743 [debug] Using HTTP_PROXY: http://proxy:8080
12:29:12.743 [debug] Using HTTPS_PROXY: http://proxy:8080
== Compilation error in file lib/mdex/native.ex ==
** (RuntimeError) Error while downloading precompiled NIF: couldn't fetch NIF from https://github.com/leandrocp/mdex/releases/download/v0.1.14/libcomrak_nif-v0.1.14-nif-2.15-x86_64-unknown-linux-gnu.so.tar.gz: {:ok, {{~c"HTTP/1.1", 503, ~c"Service Unavailable"}, [{~c"date", ~c"Mon, 08 Sep 2025 12:29:12 GMT"}, {~c"server", ~c"envoy"}, {~c"content-length", ~c"85"}, {~c"content-type", ~c"text/plain"}], "upstream connect error or disconnect/reset before headers. reset reason: remote reset"}}.
You can force the project to build from scratch with:
config :rustler_precompiled, :force_build, mdex: true
In order to force the build, you also need to add Rustler as a dependency in your `mix.exs`:
{:rustler, ">= 0.0.0", optional: true}
lib/mdex/native.ex:9: (module)
could not compile dependency :mdex, "mix compile" failed. Errors may have been logged above. You can recompile this dependency with "mix deps.compile mdex --force", update it with "mix deps.update mdex" or clean it with "mix deps.clean mdex"
Does it work without a proxy? Is the proxy a hard requirement?
AFAIK itās a requirement. All traffic runs through the proxy for security reasons:
Environments run behind an HTTP/HTTPS network proxy for security and abuse prevention purposes. All outbound internet traffic passes through this proxy.
Cloud environments (source)
For more context, this is an issue during the āinstall dependencyā phase where internet access is enabled by default.
I see. Well, HTTP 503 can mean anything really, Iāve seen it used in cases where it was actually HTTP 400. No idea, sorry. Donāt have enough context.
I had the following in my setup script from a combination of several answers, which make the agent seemingly running tests and formatting.
install -Dm644 "$CODEX_PROXY_CERT" /usr/local/share/ca-certificates/codex-proxy.crt
update-ca-certificates
echo 'export ERL_SSL_CACERTFILE=/etc/ssl/certs/ca-certificates.crt' >> ~/.bashrc
echo 'export HEX_CACERTS_PATH=/etc/ssl/certs/ca-certificates.crt' >> ~/.bashrc
export ERL_SSL_CACERTFILE=/etc/ssl/certs/ca-certificates.crt
export HEX_CACERTS_PATH=/etc/ssl/certs/ca-certificates.crt
# Downloading patched hex
mix archive.install --force github 650health/hex branch latest
# Install rebar3 manually.
curl -L -o rebar3 https://s3.amazonaws.com/rebar3/rebar3
chmod +x ./rebar3
./rebar3 local install
export PATH=/root/.cache/rebar3/bin:$PATH
mix local.rebar rebar3 $(which rebar3)
mix deps.get
And just the following in my maintenance script.
mix deps.get
I had to enable full internet access though, as it seems that some dependencies were still fetched after the setup step.
The underlying bug has been fixed in OTP and Elixir will work in Codex Cloud with the latest Erlang patches.
We patched erlang/otp httpc module. It has been released in OTP 28.1, 27.3.4.3 and 26.2.5.15. mix deps.get now works as expected since httpc no longer sends the te header for default GET requests.
Thanks @Damirados for the sample using Mise en Place. This works:
# make sure mise + its shims are on PATH now and later
echo 'export PATH=$HOME/.local/bin:$PATH' >> ~/.bashrc
echo 'export PATH=$HOME/.local/share/mise/shims:$PATH' >> ~/.bashrc
echo 'export HEX_CACERTS_PATH=$CODEX_PROXY_CERT' >> ~/.bashrc
export PATH=$HOME/.local/bin:$PATH
export PATH=$HOME/.local/share/mise/shims:$PATH
export HEX_CACERTS_PATH=$CODEX_PROXY_CERT
mise use --global erlang@28.1
mise use --global elixir@1.18.4-otp-28
mix deps.get
mix deps.compile
mix compile
I am still not able to compile, this time due to Cldr it seems.
== Compilation error in file lib/professional_profiles/cldr.ex ==
** (CaseClauseError) no case clause matching: {:error, {:failed_connect, [{:to_address, {~c"raw.githubusercontent.com", 443}}, {:tls, [verify: :verify_peer, cacertfile: ~c"/workspace/app-professional-profiles/_build/test/lib/castore/priv/cacerts.pem", depth: 4, ciphers: [%{prf: :sha256, mac: :aead, cipher: :aes_128_gcm, key_exchange: :any}, %{prf: :sha384, mac: :aead, cipher: :aes_256_gcm, key_exchange: :any}, %{prf: :sha256, mac: :aead, cipher: :chacha20_poly1305, key_exchange: :any}, %{prf: :sha256, mac: :aead, cipher: :aes_128_gcm, key_exchange: :ecdhe_ecdsa}, %{prf: :sha256, mac: :aead, cipher: :aes_128_gcm, key_exchange: :ecdhe_rsa}, %{prf: :sha384, mac: :aead, cipher: :aes_256_gcm, key_exchange: :ecdh_ecdsa}, %{prf: :sha384, mac: :aead, cipher: :aes_256_gcm, key_exchange: :ecdh_rsa}, %{prf: :sha256, mac: :aead, cipher: :chacha20_poly1305, key_exchange: :ecdhe_ecdsa}, %{prf: :sha256, mac: :aead, cipher: :chacha20_poly1305, key_exchange: :ecdhe_rsa}, %{prf: :sha256, mac: :aead, cipher: :aes_128_gcm, key_exchange: :dhe_rsa}, %{prf: :sha384, mac: :aead, cipher: :aes_256_gcm, key_exchange: :dhe_rsa}], versions: [:"tlsv1.2", :"tlsv1.3"], eccs: [:secp384r1, :secp256r1], reuse_sessions: true, server_name_indication: ~c"raw.githubusercontent.com", secure_renegotiate: true, customize_hostname_check: [match_fun: #Function<6.112534691/2 in :public_key.pkix_verify_hostname_match_fun/1>]], {:tls_alert, {:unknown_ca, ~c"TLS client: In state wait_cert_cr at ssl_handshake.erl:2183 generated CLIENT ALERT: Fatal - Unknown CA\n"}}}]}}
(cldr_utils 2.28.3) lib/cldr/http/http.ex:281: Cldr.Http.get_with_headers/2
(cldr_utils 2.28.3) lib/cldr/http/http.ex:120: Cldr.Http.get/2
(ex_cldr 2.43.1) lib/cldr/install.ex:104: Cldr.Install.do_install_locale_name/3
(elixir 1.18.4) lib/enum.ex:987: Enum."-each/2-lists^foreach/1-0-"/2
(ex_cldr 2.43.1) lib/cldr/install.ex:29: Cldr.Install.install_known_locale_names/1
(ex_cldr 2.43.1) lib/cldr.ex:102: Cldr.install_locales/1
(ex_cldr 2.43.1) expanding macro: Cldr.Backend.Compiler.__before_compile__/1
lib/professional_profiles/cldr.ex:1: ProfessionalProfiles.Cldr (module)
This is my āsetupā
cd /workspace/app-professional-profiles
mise install
echo 'export PATH=$HOME/.local/bin:$PATH' >> ~/.bashrc
echo 'export PATH=$HOME/.local/share/mise/shims:$PATH' >> ~/.bashrc
echo 'export HEX_CACERTS_PATH=$CODEX_PROXY_CERT' >> ~/.bashrc
export PATH=$HOME/.local/bin:$PATH
export PATH=$HOME/.local/share/mise/shims:$PATH
export HEX_CACERTS_PATH=$CODEX_PROXY_CERT
# Activate mise for the current session
eval "$(mise activate -q bash)"
mix local.hex --force
mix deps.get
mix test
ex_cldr uses Erlangās :httpc module to download configured locales at compile time. The error seems to be CLIENT ALERT: Fatal - Unknown CA which is a surprise to me - Iām not even sure which CA is in effect at the time you are compiling (and I am far from knowledgable about CAs). Iāve fixed the case clause error on the development branch but that doesnāt resolve the underlying error.
Ultimately it is Cldr.Http.get/2 that does the work and it has two options you might try to see if you can at least get around the error for now:
- Set the env variable
CLDR_UNSAFE_HTTPS=true(not recommended for production) - Configure (in
config.exssince itās required for compile time) a different certificate store and see if that connects as expected. The error message indicates you have castore configured and itās using that libraries certificate store - which is very common. Maybe you can see if there is a later version than what you have installed? There was a new version on August 12th. - You can test by doing:
iex> `Cldr.Http.get("Cldr.Http.get("https://raw.githubusercontent.com/elixir-cldr/cldr/refs/tags/v2.43.2/priv/cldr/locales/en.json")")`
These options are discussed in the documentation but added here to make it hopefully easier for you to access:
Unsafe HTTPS
If the environment variable CLDR_UNSAFE_HTTPS is
set to anything other than FALSE, false, nil
or NIL then no peer verification of certificates
is performed. Setting this variable is not recommended
but it may be required where peer verification fails for
unidentified reasons. Please open an issue
if this occurs.
Certificate stores
In order to keep dependencies to a minimum,
get/1 attempts to locate an already installed
certificate store. It will try to locate a
store in the following order which is intended
to satisfy most host systems. The certificate
store is expected to be a path name on the
host system.
# A certificate store configured by the
# developer
Application.get_env(:ex_cldr, :cacertfile)
# Populated if hex package `CAStore` is configured
CAStore.file_path()
# Populated if hex package `certfi` is configured
:certifi.cacertfile()
# Debian/Ubuntu/Gentoo etc.
"/etc/ssl/certs/ca-certificates.crt",
# Fedora/RHEL 6
"/etc/pki/tls/certs/ca-bundle.crt",
# OpenSUSE
"/etc/ssl/ca-bundle.pem",
# OpenELEC
"/etc/pki/tls/cacert.pem",
# CentOS/RHEL 7
"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem",
# Open SSL on MacOS
"/usr/local/etc/openssl/cert.pem",
# MacOS & Alpine Linux
"/etc/ssl/cert.pem"






















