Codex Only Gets the Environment You Gave It

One of the small traps with Codex CLI is that a project can look configured while the process running the work is not configured at all.

That sounds like a technical distinction.

It is.

But it is also the difference between solving the real problem and spending an hour debugging the wrong thing.

In a recent local automation session, the setup looked sensible at first glance. There was a secrets file on disk. The project had a known place for environment values. The workflow expected an auth token called `ENV_TOKEN`.

So the natural assumption was:

The secret exists, therefore the workflow should be authenticated.

Then we checked the actual runtime:

`python3 -c "import os; print(bool(os.getenv('ENV_TOKEN')))"`

It printed `False`.

That was the useful answer.

Not the most comforting answer, but the useful one.

The file existed. The current process did not have the variable.

If you are learning Codex, this is worth slowing down for. Codex does not automatically read every `.env`, `.envrc`, profile script, or secrets directory on your machine. It starts as a process inside a shell session. It inherits the environment that shell gives it. Then, when Codex runs a command, that command inherits from Codex.

The chain is ordinary:

Your shell starts Codex.

Codex starts a command.

That command checks `os.getenv()`.

If the value was not loaded before Codex started, the later command may never see it.

This is why a repo can feel ready and still fail inside an agent workflow.

You may have a file like `~/secrets/project.env`.

You may have `direnv` installed.

You may know the project works when you run it manually in your terminal.

But none of that proves the Codex process has the variable right now.

The process environment is the thing that counts.

Tools like `direnv` can make this easy to miss because they make local development feel automatic. You enter a directory, the environment loads, and after a while it feels like those variables belong to the machine.

They do not.

They belong to that shell session.

Once an agent, subprocess, task runner, or non-interactive command enters the picture, you need to be more explicit about what environment crossed the boundary.

The beginner rule is simple:

Before debugging the API client, verify the environment inside the same runtime path that will run the command.

Not in another terminal.

Not by checking whether the secrets file exists.

Not by assuming `direnv` handled it.

Ask the runtime that matters.

If Codex is about to run a Python script that needs `ENV_TOKEN`, first have Codex run:

`python3 -c "import os; print(bool(os.getenv('ENV_TOKEN')))"`

If that prints `False`, the problem is not yet the Python script.

It is not yet the API.

It is not yet the workflow logic.

The process is simply unauthenticated.

That changes the fix.

The fix is not only to document where the secret file lives. That may be useful, but it is incomplete.

The stronger fix is to document how the secret gets loaded before Codex starts, and how to verify that Codex can see it.

Run Codex from a shell where the project environment has already been loaded.

If the repo uses `direnv`, make sure `direnv allow` has been run and the shell has actually loaded the `.envrc`.

Before running the workflow, verify the required token from inside the Codex command environment.

That habit is more reliable than saying, "the file is there."

A file on disk is a source.

An environment variable in the current process is runtime state.

Codex works with runtime state.

This small distinction explains many local automation failures. A command fails with an auth error. The project owner knows the secret exists. The agent can see the path. Everyone starts looking at code, requests, endpoints, and client libraries.

But the better first question is narrower:

Does this process have the variable it needs, right now?

If the answer is no, fix that first.

Once the environment is actually present, then it makes sense to debug the code, the request, the API response, or the workflow itself.

This is one of those lessons that feels obvious after you have seen it clearly.

Codex is powerful, but it is still bound by ordinary process rules. It can only pass along the environment it was given. It can only run commands with the variables and permissions available to that session.

So when a Codex workflow needs secrets, make the contract explicit:

Load the project environment.

Start Codex from that shell.

Verify the required variables from inside the runtime.

Then run the automation.

That small check will not solve every failure.

It will stop you from debugging the wrong one.

-----------
If you find this content useful, please share it with this link: [https://patrickmichael.co.za/subscribe](https://patrickmichael.co.za/subscribe)

Classification