Non-Interactive Mode Fails to Authenticate Using Provided API Key

Resolved 💬 16 comments Opened Mar 18, 2025 by potproject Closed Apr 2, 2025
💡 Likely answer: A maintainer (bcherny, collaborator) responded on this thread — see the highlighted reply below.

Environment

  • Platform (select one):
  • [X] Anthropic API
  • [ ] AWS Bedrock
  • [ ] Google Vertex AI
  • [ ] Other: <!-- specify -->
  • Claude CLI version: 0.2.48
  • Operating System: Ubuntu (via Docker)
  • Terminal: Docker container

Bug Description

In a non-interactive environment, the CLI still requires executing /login even though an API key is provided. The documentation states that CI automation should work, but in my setup, running claude non-interactively results in the error "Invalid API key · Please run /login." While interactive sessions work fine after manually logging in with /login, this behavior prevents the tool from being used in automated CI workflows (such as GitHub Actions).

Steps to Reproduce

  1. Build a Docker image with the following Dockerfile:

``dockerfile
FROM ubuntu:latest
USER root
WORKDIR /home/app
RUN apt-get update
RUN apt-get -y install curl git
RUN curl -sL https://deb.nodesource.com/setup_20.x | bash -
RUN apt-get -y install nodejs
RUN npm install -g @anthropic-ai/claude-code
# Set environment variables for authentication (replace sk-xxx with your API key)
ENV ANTHROPIC_API_KEY=sk-xxx
ENTRYPOINT ["sh", "-c", "claude"]
``

  1. Run the container in non-interactive mode with the command:

``sh
docker run -it <image_id> -p "hello"
``

  1. Observe the error message:

``
Invalid API key · Please run /login
``

  1. Confirm that the ANTHROPIC_API_KEY is set by running:

``sh
docker run -it --entrypoint sh <image_id> -c 'echo $ANTHROPIC_API_KEY'
`
which outputs:
`
sk-xxx
``

Expected Behavior

Is there a known workaround or a fix planned to support non-interactive authentication?

View original on GitHub ↗

16 Comments

david-clearscale · 1 year ago

I am having the same issue. Running the latest version of Claude Code 0.2.49

indigoviolet · 1 year ago

Also on 0.2.50, seemingly works on Mac but not on Ubuntu @bcherny @levpopov

david-clearscale · 1 year ago
Also on 0.2.50, seemingly works on Mac but not on Ubuntu @bcherny @levpopov

I am on Mac, running Claude Code in a Docker container, env var ANTHROPIC_API_KEY is set, and still getting the message that it's an invalid API key and I need to run /login. Updated to 0.2.50

todorkolev · 1 year ago

Same with Claude Code 0.2.53 (Ubuntu 22.04.5 LTS docker container on MacOS)

reverie · 1 year ago

Looking into this. It seems like a potential workaround is to use ENTRYPOINT ["claude"] instead. Please let me know if this works for you.

sjourdan · 1 year ago

same problem here, using my own keys or a special key generated by Anthropic support (I just pointed them to this thread too)

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 24.04.2 LTS
Release:        24.04
Codename:       noble
$ ANTHROPIC_API_KEY=sk-ant... claude -p "hello"
Invalid API key · Please run /login
$ claude -v
0.2.53 (Claude Code)
sjourdan · 1 year ago

I asked claude to read its own code and find the issue (_"read the code from /usr/bin/claude and find why using ANTHROPIC_API_KEY doesn't work when run in headless mode using -p"_)

{
  "cost_usd": 1.2548647000000004,
  "duration_ms": 250381,
  "duration_api_ms": 250382,
  "result": "After examining the code, I can see why `ANTHROPIC_API_KEY` environment variable doesn't work when running in headless mode with the `-p` flag. Here is the relevant information:\n\n1. In the function `Sw(I)` (likely standing for \"Swap\" or \"Switch API Key\"), there's code that handles API key selection with different logic paths based on certain conditions:\n\n```javascript\nfunction Sw(I) {\n    let Z = i0();\n    if (I && process.env.ANTHROPIC_API_KEY)\n        return process.env.ANTHROPIC_API_KEY;\n    if (!1 === \"true\") {\n        if (!process.env.ANTHROPIC_API_KEY)\n            throw new Error(\"ANTHROPIC_API_KEY env var is required\");\n        return process.env.ANTHROPIC_API_KEY;\n    } {\n        let G = Lk();\n        if (G)\n            return G;\n        return M41();\n    }\n    return null;\n}\n```\n\n2. The issue is that the parameter `I` controls whether the environment variable is used. When running in headless mode with `-p`, this parameter is set to `false`, causing the API key selection logic to bypass the environment variable and look for a stored key instead.\n\n3. The code includes a function `fU2(I)` that validates API keys against an approved list stored in the user's configuration. Only keys that have been previously approved are accepted.\n\nWhen you run with `-p` flag (headless mode), the code path calls `Sw(false)`, which skips checking the environment variable and instead tries to use the stored API key from the system's credential storage (Keychain on macOS), or from the application's own configuration.\n\nTo make it work in headless mode, you would need to either:\n\n1. Use the stored API key that was previously set up and approved during interactive mode\n2. Modify the code to check the environment variable in headless mode too"
}

I don't have the time right now to check this - just sharing in case someone else is looking at it!

sjourdan · 1 year ago

I confirm that claude could fix itself (using v0.2.54)

The function Sw(I) is responsible for API key validation and selection.

Here's the buggy snippet:

function Sw(I) {
  let Z = i0();
  if (I && process.env.ANTHROPIC_API_KEY) 
    return process.env.ANTHROPIC_API_KEY;
  if (!1 === "true") {
    if (!process.env.ANTHROPIC_API_KEY)
      throw new Error("ANTHROPIC_API_KEY env var is required");
    return process.env.ANTHROPIC_API_KEY;
  }
  let G = Lk();
  if (G) return G;
  return M41();
  return null;
}

Change the function to this:

function Sw(I) {
  let Z = i0();
  // Always check environment variable first
  if (process.env.ANTHROPIC_API_KEY) 
    return process.env.ANTHROPIC_API_KEY;
  // Fall back to stored key if no environment variable
  let G = Lk();
  if (G) return G;
  return M41();
  return null;
}

...and voila:

$ ANTHROPIC_API_KEY="sk-ant-api03-..." claude -p "hi"
Hello! I'm here to help you with software engineering tasks. How may I assist you today?

I think it's my first contrib to a non-open-source software, and also my first using a software to fix itself!

potproject · 1 year ago

I built a Docker container based on .devcontainer/Dockerfile and confirmed that it runs without any issues—the "Invalid API key · Please run /login" error did not occur.

Since this code is not open source, it's quite difficult to pinpoint the exact cause. However, it's likely that the issue with failing to retrieve the key properly lies in the internal shell version or one of the dependent libraries.

bcherny collaborator · 1 year ago

Fix landing in the next version. Thanks for the reports!

bcherny collaborator · 1 year ago

Fixed in 0.2.59. Restart to update.

confususs · 1 year ago

I think this issue has resurfaced:

~/dev/reproduce
➜ claude --version
0.2.90 (Claude Code)

~/dev/reproduce
➜ claude -p "hello"
Invalid API key · Please run /login

But when I start a session by calling claude it just picks up on my API key.

RVCA212 · 1 year ago

I'm getting this issue too with the 0.2.90 version!

sergey-suslov · 1 year ago

I am getting the same on v1.0.11

pseudotensor · 1 year ago

Same on 1.0.43. APi key is certainly valid

github-actions[bot] · 11 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.