← Back to Blog
For: AI Engineers, ML Engineers, Platform Engineers, AI Systems Architects

Claude Code on Enterprise WSL: Eleven Errors, Eleven Fixes, and the One Flag Nobody Documents (--bare)

Why Claude Code fails on a corporate laptop in eleven specific ways, and the single flag that closes the cascade.

#claude-code#wsl#enterprise#corporate-network#ssl-inspection#nodejs#developer-experience

You set ANTHROPIC_API_KEY. You run claude. A browser tab opens to https://platform.claude.com/oauth/. You stare at it. You have an enterprise API key. You do not have a Claude.ai account. You cannot complete the flow.

If your company licensed Claude Code with OAuth-based user provisioning (Teams, Enterprise, SSO), you would not see this screen. The CLI would hand you off to your identity provider and you would be working in minutes. This article is not for you. It is for the rest of us: developers whose companies procured Anthropic API access, provisioned us keys, and stopped there.

For that case, Anthropic shipped a fix and forgot to document it. The flag is --bare. It is one line deep in claude --help. It is the most important undocumented flag in the tool, and it has been in the binary for months without making it into the install guide, the quickstart, or any of the dozens of "how to install Claude Code on Windows" articles indexed by Google.

The Thesis

Claude Code has two well-supported auth paths: OAuth (for Claude.ai Pro, Max, Teams, and Enterprise license holders) and API key (for direct API access). Both work. The gap is the third case nobody documents: an enterprise that provisions API keys to its developers without giving them OAuth-based Claude.ai accounts.

For those developers - and there are many of us - the default auth flow tries OAuth first, opens a browser to platform.claude.com, and stalls. The ANTHROPIC_API_KEY env var is set and claude auth status reports "loggedIn": true, but the CLI still redirects. Combined with corporate SSL inspection, blocked external repos, and stripped-down WSL distros, the result is eleven distinct failure modes that cascade into each other.

The single fix that closes the cascade is --bare. Until Anthropic surfaces it in the enterprise setup docs, every API-key-only developer rediscovers the same eleven walls in the same order, losing the same afternoon.

This article walks the cascade, names the pattern, and gives you the setup script your team should have been handed on day one.

Why This Matters

The install path Anthropic ships works in roughly two minutes on a personal MacBook with a Claude.ai subscription. On a corporate Windows laptop with WSL, SSL inspection, an API-key-only license, and no Claude.ai account, the same path takes most engineers a full afternoon. That gap is not a tool problem. It is an unaddressed deployment pattern.

Most existing articles cover one or two of the eleven failures. None I could find walk the full cascade or surface --bare. The result is that every API-key-only developer rediscovers the same path independently, in the same order.

If you are deploying Claude Code across an API-key-only team, you need to know this cascade exists so you can document the fixes upfront. If you are an individual developer hitting wall after wall, you need to know there are eleven walls, not infinity walls, and they end at a flag.

The Eleven Errors Every Enterprise Claude Code Install Hits

Each error in this section produces the next. The order matters. Skipping ahead does not work because each fix unlocks the next failure mode.

Before walking it, name the pattern. Every failure below has the same root cause: the tool ships with personal-machine defaults in a context where the user is on a corporate-machine setup. I call this the Personal-Default Trap - and once you see it, you start spotting it in every developer tool you touch. We will return to it after the cascade.

Error 1: You Think You Are in WSL Ubuntu. You Are Not.

You open a terminal labelled "WSL" and run curl https://claude.ai/install.sh | bash. It fails. You assume the problem is the script.

The real problem is identity. Run:

code
cat /etc/os-release

If it returns PRETTY_NAME="Docker Desktop", you are not in WSL Ubuntu. You are inside Docker Desktop's Alpine container, which Windows exposes through the WSL command palette. Alpine uses musl libc instead of glibc, ships with ash instead of bash, and uses apk instead of apt. Almost every Claude Code install script assumes Debian/Ubuntu.

The fix: Exit. Install a real WSL Ubuntu distribution from PowerShell:

code
wsl --install -d Ubuntuwsl -d Ubuntu

Verify with cat /etc/os-release again. You should see NAME="Ubuntu".

Error 2: SSL Certificate Verification Fails on curl, wget, and pip

code
SSL certificate problem: unable to get local issuer certificate

Your corporate network runs TLS inspection. Every HTTPS connection is intercepted, decrypted, and re-encrypted with a corporate CA that your fresh WSL Ubuntu has never seen.

curl -k (insecure mode) usually fails too because the corporate proxy is also doing connection-level filtering that returns Connection reset by peer before the TLS handshake completes.

The fix: Get the corporate root CA from your IT team as a PEM file. Then:

code
sudo cp corporate-root-ca.pem /usr/local/share/ca-certificates/corporate-root-ca.crtsudo update-ca-certificatesexport NODE_EXTRA_CA_CERTS=/usr/local/share/ca-certificates/corporate-root-ca.crt

Add the export to ~/.bashrc. Without NODE_EXTRA_CA_CERTS, Node-based tools (Claude Code, npm, every Node MCP server) will fail even after the system CA store accepts the cert.

Never use NODE_TLS_REJECT_UNAUTHORIZED=0. It silences errors and surrenders certificate validation entirely. Your API key travels in plaintext to anything sitting on the path.

Error 3: Core Tools Are Missing

code
-sh: sudo: not found-sh: apt: not found-sh: curl: not found

You are in a minimal container or a stripped-down distro. The script you copy-pasted assumes a full developer image.

The fix: Install the basics. For Ubuntu:

code
apt updateapt install bash curl wget sudo ca-certificates -y

For Alpine (if you decided to stay):

code
apk updateapk add bash curl wget sudo ca-certificates

Different commands for different distros. There is no portable answer. This is why Error 1 matters - identifying the distro first saves you from running the wrong commands for ten minutes.

Personal-Default Trap signature: install scripts assume a developer image with bash, curl, and sudo preinstalled. Corporate base images often strip these.

Error 4: The Install Script Uses Bash Syntax in a Posix Shell

code
sh: syntax error: unexpected "(" (expecting "then")

The script is bash. The interpreter handling the pipe is sh (often dash or ash). Bash arrays, parameter expansion, and process substitution do not work.

The fix: Pipe to bash explicitly:

code
curl -fsSL https://claude.ai/install.sh | bash

Or download first, then run:

code
wget -O install.sh https://claude.ai/install.shbash install.sh

Error 5: npm Hits SSL Issues Even After System CA Is Fixed

npm install -g @anthropic-ai/claude-code fails with certificate errors despite update-ca-certificates working. npm has its own CA configuration, separate from the system.

The fix:

code
npm config set cafile /usr/local/share/ca-certificates/corporate-root-ca.crtnpm config set strict-ssl false  # only if cafile approach fails

The cafile approach is correct. Disabling strict-ssl is the lazy fix that comes back to bite you when an MCP server tries to make its own HTTPS calls.

Error 6: Node.js Version Is Too Old

Ubuntu 22.04 ships with Node.js v12 in its default apt repos. Claude Code requires v18+. You hit:

code
npm WARN EBADENGINE Unsupported engine

Followed by a syntax error from install.cjs because v12 does not understand the optional chaining operator (?.).

The fix in a normal environment: Add NodeSource's repo and install Node.js 18.

The fix in your environment: NodeSource's repo lives at deb.nodesource.com, which your corporate proxy will probably block with the same SSL handshake failure from Error 2. nvm lives on raw.githubusercontent.com, also blocked. Both fail in the same way.

You have to install Node.js manually:

  1. On Windows, download node-v18.20.8-linux-x64.tar.xz from nodejs.org (if Windows is outside the proxy or has whitelisted nodejs.org)
  2. Transfer into WSL:
code
cp /mnt/c/Users/YourName/Downloads/node-v18.20.8-linux-x64.tar.xz ~/cd ~tar -xf node-v18.20.8-linux-x64.tar.xzsudo mv node-v18.20.8-linux-x64 /usr/local/nodeecho 'export PATH="/usr/local/node/bin:$PATH"' >> ~/.bashrcsource ~/.bashrcnode --version  # v18.20.8

This is what the rest of the install assumes.

Personal-Default Trap signature: install scripts assume external package repositories (NodeSource, nvm, npm registry) are reachable. Corporate proxies block them.

Error 7: npm Permission Denied on Global Install

code
npm error path /usr/local/lib/node_modulesnpm error errno -13npm error EACCES: permission denied

The classic Linux npm-global trap. sudo npm install -g is tempting, but it creates a permission mess that haunts you forever.

The fix: Configure npm to use a user-local prefix:

code
mkdir -p ~/.npm-globalnpm config set prefix ~/.npm-globalecho 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrcsource ~/.bashrcnpm install -g @anthropic-ai/claude-code

Error 8: which claude Points to a Windows Binary

You finally install Claude Code in WSL Ubuntu. You run which claude. It returns:

code
/mnt/c/Users/ranjan.kumar/AppData/Roaming/npm/claude

Windows npm is on your WSL PATH because WSL inherits the Windows PATH by default. Your shell finds the Windows claude.exe first, before it finds the Linux binary you just installed.

Verify with claude doctor:

code
Platform: win32-x64Path: C:\Users\...\node_modules\@anthropic-ai\claude-code\bin\claude.exe

That is the Windows version running under WSL via interop. It behaves differently from the Linux version.

The fix: Put Linux paths in front of Windows paths. At the top of ~/.bashrc:

code
export PATH="/usr/local/node/bin:$HOME/.npm-global/bin:$PATH"

Then source ~/.bashrc. Verify:

code
which claude# /home/your-user/.npm-global/bin/claudeclaude doctor | grep Platform# Platform: linux-x64

Error 9: Your Python venv Lives on a Windows Path

You are working on a Python project. You run python3 -m venv venv inside /mnt/c/Users/.../OneDrive - Reliance.../PROJECTS/myapp/backend. It seems to work.

Then pip install -e ".[dev]" fails with:

code
pip._vendor.pyproject_hooks._impl.BackendUnavailable:Cannot import 'setuptools.backends.legacy'

The venv is technically on disk, but every file operation passes through the WSL-Windows file system bridge. Symlinks, line endings, and file locking behave unpredictably. OneDrive's background sync makes it worse. The setuptools install ends up half-broken.

The fix: Never create Python venvs on Windows paths from WSL. Copy the project into WSL's native filesystem:

code
cp -r "/mnt/c/Users/YourName/OneDrive - Corp/PROJECTS/myapp" ~/myappcd ~/myapp/backendrm -rf venvpython3 -m venv venvsource venv/bin/activatepip install --upgrade pip setuptools wheelpip install -e ".[dev]"

Same code, native filesystem, immediate success. This is also why Anthropic recommends working inside ~/projects/... instead of /mnt/c/....

Error 10: pyproject.toml Uses a Deprecated Build Backend

If you inherited the codebase, it might have:

code
[build-system]requires = ["setuptools>=68"]build-backend = "setuptools.backends.legacy:build"

setuptools.backends.legacy was removed in recent setuptools releases. The error you get from Error 9 is partly this.

The fix: Replace it with the modern backend:

code
[build-system]requires = ["setuptools>=68", "wheel"]build-backend = "setuptools.build_meta"

Error 11: claude Opens a Browser Despite ANTHROPIC_API_KEY Being Set

This is the wall that ends most enterprise install attempts. It is also the canonical example of the Personal-Default Trap: the tool is configured correctly for an enterprise context, the env var is set, the auth status reports "loggedIn": true, and the CLI still tries to OAuth as if you were a Pro subscriber on a personal MacBook.

You have done everything right. which claude returns the Linux binary. node --version is v18+. echo $ANTHROPIC_API_KEY prints your enterprise key. claude auth status returns:

code
{  "loggedIn": true,  "authMethod": "api_key",  "apiProvider": "firstParty",  "apiKeySource": "ANTHROPIC_API_KEY"}

You run claude. A browser tab opens to https://platform.claude.com/oauth/. The CLI sits there waiting for OAuth to complete. You have no Claude.ai account. There is nothing to log into.

The auth flow on certain versions of Claude Code prefers OAuth even when an API key is configured. The CLI silently falls back to OAuth as a "first-class" path, ignoring the env var unless you explicitly tell it otherwise.

The fix that closes the cascade:

code
claude --bare

The --bare flag is documented one line deep in claude --help:

Anthropic auth is strictly ANTHROPIC_API_KEY or apiKeyHelper via --settings (OAuth and keychain are never read).

That sentence is the entire fix for the last failure mode. It does not appear in the install guide, the quickstart, the enterprise setup docs, or any tutorial I could find. It is the most important undocumented flag in the tool.

Make it permanent. Create an alias:

code
echo 'alias claude="claude --bare"' >> ~/.bashrcsource ~/.bashrc

Or set the env var that produces the same effect:

code
export CLAUDE_CODE_SIMPLE=1

Both skip OAuth, keychain reads, hooks, LSP, plugin sync, and CLAUDE.md auto-discovery. For an enterprise install with an API key, that is exactly what you want.

The Right Way: A Clean Install Script for Corporate WSL

Here is the install path I now run on every new enterprise WSL setup. It assumes you have:

  • A WSL Ubuntu distro (not Docker Desktop Alpine)
  • The corporate root CA as a PEM file
  • An enterprise ANTHROPIC_API_KEY
  • Node.js 18+ tarball downloaded to Windows (one-time)
code
#!/bin/bashset -e# 1. System CA trustsudo cp ~/corporate-root-ca.pem /usr/local/share/ca-certificates/corporate-root-ca.crtsudo update-ca-certificates# 2. Node.js manual installcd ~tar -xf node-v18.20.8-linux-x64.tar.xzsudo mv node-v18.20.8-linux-x64 /usr/local/node# 3. PATH and env vars (put Linux first, before Windows interop)cat >> ~/.bashrc << 'EOF'export PATH="/usr/local/node/bin:$HOME/.npm-global/bin:$PATH"export NODE_EXTRA_CA_CERTS=/usr/local/share/ca-certificates/corporate-root-ca.crtexport ANTHROPIC_API_KEY="sk-ant-your-enterprise-key"alias claude="claude --bare"EOFsource ~/.bashrc# 4. npm configmkdir -p ~/.npm-globalnpm config set prefix ~/.npm-globalnpm config set cafile /usr/local/share/ca-certificates/corporate-root-ca.crt# 5. Claude Codenpm install -g @anthropic-ai/claude-code# 6. Verifywhich claudeclaude doctor

Save this as setup-claude-code-enterprise.sh, commit it to your team's onboarding repo, and stop losing afternoons.

The Named Concept: The Personal-Default Trap

Every failure in this cascade has the same root cause: the tool was designed for a personal-machine context and ships with personal-machine defaults. The defaults are not malicious. They are reasonable when the user is on a residential connection with a personal Claude.ai account. They become eleven cascading failures the moment the user is on a corporate network with an enterprise API key.

I call this the Personal-Default Trap: when a developer tool's defaults are optimized for a personal-machine context, every enterprise deployment becomes a multi-hour exercise in reversing those defaults, and the reverse-path is rarely documented.

The trap has a signature:

  • The personal install is "one command, two minutes"
  • The enterprise install hits five to fifteen distinct failures
  • Each failure has a fix, but the fixes are scattered across StackOverflow, GitHub issues, and corporate IT wikis
  • The tool ships an "enterprise mode" flag that closes most of the gap, but it is buried in help text

You will recognize the trap in npm, pip, git, docker, every Node CLI, every Python CLI, and now Claude Code. The fix is the same every time: identify the flag (--bare here), document the cascade, and write a setup script your team can copy-paste.

Deep Dive: When the OAuth Default Is Wrong (and When It Isn't)

A short defense of the narrowed contrarian position.

Anthropic ships OAuth-first because it is the right default for most users. Claude.ai Pro and Max subscribers get a clean OAuth flow. Enterprises that license Claude with OAuth-based user provisioning (Teams, Enterprise plans with SSO) get OAuth that works through their existing identity provider. In both cases, OAuth doubles as billing attribution, the keychain stores tokens more securely than env vars, and the developer experience is one command.

OAuth-first becomes the wrong default in one specific case: the API-key-only enterprise developer. That is a developer whose company has procured Anthropic API access and provisions keys to engineers, but does not give those engineers OAuth-based Claude.ai accounts. The developer has a valid ANTHROPIC_API_KEY. They have no Claude.ai login. They have no way to complete the OAuth flow even if the corporate proxy whitelisted platform.claude.com.

In this case:

  • The user has an API key, not a Claude.ai account
  • The OAuth redirect lands somewhere they cannot authenticate against
  • The OS keychain may be sandboxed or unavailable inside WSL
  • Creating a personal Claude.ai account on a corporate machine is often against policy

This is a real and common deployment pattern, especially for organizations that started with API access for backend services and later expanded to developer CLI tools without renegotiating the licensing model. For these developers, the CLI should detect that only an API key is present, no OAuth session is initiated, and switch defaults silently. Today it does not. ANTHROPIC_API_KEY set with no prior claude auth login should be enough to bypass OAuth automatically.

Until that ships, --bare is the workaround that should be in every API-key-only enterprise install guide.

Diagram: The Cascade in Three Layers

The eleven errors group naturally into three layers: environment (you are in the wrong shell or distro), toolchain (Node, npm, paths, certs), and runtime (auth). The cascade resolves layer-by-layer.

mermaid
flowchart TD
    Start[Start: claude install on corporate WSL] --> L1

    subgraph L1[Layer 1: Environment]
        E1[Error 1: Docker Desktop, not Ubuntu]
        E2[Error 2: SSL inspection breaks curl/wget/pip]
        E3[Error 3: Missing bash, curl, sudo]
        E4[Error 4: sh cannot run bash syntax]
    end

    subgraph L2[Layer 2: Toolchain]
        E5[Error 5: npm cafile not configured]
        E6[Error 6: Node v12, need v18+]
        E7[Error 7: npm EACCES on global install]
        E8[Error 8: Windows claude.exe on PATH]
    end

    subgraph L3[Layer 3: Project + Runtime]
        E9[Error 9: venv on Windows path corrupts]
        E10[Error 10: legacy setuptools backend]
        E11[Error 11: OAuth redirect ignores API key]
    end

    L1 --> L2 --> L3 --> Fix

    Fix["Fix: claude --bare<br/>(closes the cascade)"] --> Done[Claude Code running on enterprise API key]

    style Start fill:#4A90E2,color:#fff
    style L1 fill:#FFD93D,color:#000
    style L2 fill:#FFA07A,color:#fff
    style L3 fill:#9B59B6,color:#fff
    style E1 fill:#E74C3C,color:#fff
    style E2 fill:#E74C3C,color:#fff
    style E3 fill:#E74C3C,color:#fff
    style E4 fill:#E74C3C,color:#fff
    style E5 fill:#E74C3C,color:#fff
    style E6 fill:#E74C3C,color:#fff
    style E7 fill:#E74C3C,color:#fff
    style E8 fill:#E74C3C,color:#fff
    style E9 fill:#E74C3C,color:#fff
    style E10 fill:#E74C3C,color:#fff
    style E11 fill:#E74C3C,color:#fff
    style Fix fill:#7B68EE,color:#fff
    style Done fill:#6BCF7F,color:#fff

Read it top to bottom: you cannot fix Layer 3 (auth) until Layer 2 (toolchain) is sound, and you cannot fix Layer 2 until Layer 1 (environment) is correct. --bare only works once everything above it is.

Enterprise Install Checklist

Before declaring Claude Code "working" on a corporate laptop, confirm:

  1. cat /etc/os-release shows Ubuntu, not Docker Desktop or Alpine
  2. update-ca-certificates was run with the corporate root CA installed
  3. echo $NODE_EXTRA_CA_CERTS points to the corporate CA PEM file
  4. node --version shows v18.x or higher
  5. npm config get prefix returns a user-local path (~/.npm-global or similar)
  6. npm config get cafile returns the corporate CA PEM file
  7. which claude returns a Linux path, not /mnt/c/...
  8. claude doctor reports Platform: linux-x64
  9. echo $ANTHROPIC_API_KEY prints your enterprise key
  10. Your Python projects live in ~/..., not /mnt/c/...
  11. alias claude="claude --bare" is in ~/.bashrc, or CLAUDE_CODE_SIMPLE=1 is exported
  12. claude opens the CLI prompt without redirecting to a browser

Eleven errors. Eleven fixes. One checklist. Run it on every new corporate machine before anyone touches a real project.

What Anthropic Should Ship Next

Claude Code is the best agentic coding tool available right now. For users on Pro, Max, Teams, or Enterprise OAuth licenses, the install works in roughly two minutes. For API-key-only enterprise developers - the case this article is for - that path becomes a cascade of eleven failures because the auth defaults assume a context that does not match.

The fix that closes the cascade is --bare, a flag that exists in the binary and is mentioned once in the help text. Knowing it exists is the difference between a four-hour install and a thirty-minute one.

If you are an API-key-only enterprise developer, document this cascade for your team. If you are at Anthropic reading this, do three things: surface --bare in the API-access setup guide, add an auto-detect path that flips it on when ANTHROPIC_API_KEY is set without a prior OAuth session, and ship a corporate-mode claude-code-install.sh that handles CA trust, npm cafile, and PATH ordering in one command.

The Personal-Default Trap is solvable. It just has to be named first - and the API-key-only case is the place to start.

References


AI Engineering

Follow for more technical deep dives on AI/ML systems, production engineering, and building real-world applications:


Comments