Skip to main content

2 posts tagged with "VSCode"

View all tags

Fix WSL2 Cannot Access Windows Host Proxy โ€” Three Invisible Pitfalls

ยท 5 min read

Encountered this issue while using AI coding tools (Claude Code, Roo) in WSL2 that need to access APIs through the Windows host proxy. After fixing the firewall, encountered two more hidden pitfalls. Documenting all root causes and solutions.

TL;DRโ€‹

WSL2's vEthernet (WSL) virtual NIC is created on every launch. Windows Firewall cannot assign a Network Profile to it, so all inbound rules are ineffective (EnforcementStatus: NotApplicable). Don't add rules โ€” disable the firewall on that interface directly:

# Run in Windows PowerShell (Administrator)
Set-NetFirewallProfile -DisabledInterfaceAliases "vEthernet (WSL)"

Additionally, after fixing the firewall, you may encounter two more pitfalls:

  1. Dynamic IP Issue: Host IP changes after WSL/Windows restart
  2. Config Cache Issue: Stale API keys in ~/.claude.json and ~/.claude/settings.json cause auth conflicts

Problemโ€‹

Environment: Windows 10 21H2 + WSL2 2.5.10.0 (NAT mode), Clash Verge on host (port 7897, Allow LAN enabled).

Symptoms:

# Ping host from WSL โ€” no response
ping 172.22.80.1

# Test proxy port โ€” no response
nc -zv 172.22.80.1 7897

# Claude Code / Roo error
# API Error: ConnectionRefused

# But direct external access works fine
curl https://example.com # OK

On the Windows side, Clash is healthy: netstat shows 0.0.0.0:7897 listening, and Test-NetConnection localhost 7897 succeeds.

Root Cause 1: Firewall Blockingโ€‹

vEthernet (WSL) is a virtual NIC dynamically created by WSL2 on every launch. Windows Firewall's Network Profiles (Domain / Private / Public) cannot be associated with this interface.

This means:

  1. Firewall inbound rules bind to Profiles
  2. vEthernet(WSL) belongs to no Profile
  3. All inbound rules show EnforcementStatus: NotApplicable for this interface
  4. Rules are simply skipped โ€” not denied, not evaluated at all

No amount of port rules or InterfaceAlias bindings will work, because the rules never execute against this interface.

Solution 1: Fix Firewall with One Commandโ€‹

Step 1: Confirm the Root Causeโ€‹

In Windows PowerShell (Administrator):

# Check the virtual NIC
Get-NetAdapter | Where-Object { $_.Name -like "*WSL*" }

# Check rule enforcement status
Get-NetFirewallRule -DisplayName "*7897*" |
Get-NetFirewallInterfaceFilter |
Get-NetFirewallPortFilter |
Format-Table -Property * -AutoSize

If rules exist but WSL still can't connect, Profile enforcement is the issue.

Step 2: Fix with One Commandโ€‹

# Disable firewall on the WSL virtual NIC only
Set-NetFirewallProfile -DisabledInterfaceAliases "vEthernet (WSL)"

Effects:

  • Only applies to the vEthernet (WSL) virtual NIC
  • Physical adapters (Wi-Fi, Ethernet) remain fully protected
  • Setting persists across reboots

Step 3: Verifyโ€‹

# Test connectivity from WSL
nc -zv 172.22.80.1 7897
# Output: Connection to 172.22.80.1 7897 port [tcp/*] succeeded!

# Test proxy
curl -x http://172.22.80.1:7897 https://api.anthropic.com

Root Cause 2: Dynamic IP Changesโ€‹

After fixing the firewall, proxy may still fail. Why? vEthernet (WSL) IP changes on every launch.

If you hardcoded the IP in .bashrc like:

export http_proxy=http://172.22.80.1:7897  # This IP may change!

Fix: Dynamically detect host IP in .bashrc:

# Auto-detect host IP from DNS server
export WINDOWS_IP=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}')
export http_proxy="http://${WINDOWS_IP}:7897"
export https_proxy="http://${WINDOWS_IP}:7897"

Root Cause 3: Config File Cached Keysโ€‹

After fixing firewall and dynamic IP, Claude Code/GLM may still report auth conflicts. Why? Stale keys cached in:

  1. ~/.bashrc global export of ANTHROPIC_API_KEY
  2. ~/.claude.json stores previously approved keys in customApiKeyResponses.approved
  3. ~/.claude/settings.json may have hardcoded environment variables

When switching to GLM mode, unset ANTHROPIC_API_KEY works temporarily, but bashrc reload re-exports it. Claude Code reads all three sources and reports conflict.

Solution 3: Clear Cached Keysโ€‹

# 1. Check for conflicts
echo $ANTHROPIC_API_KEY $ANTHROPIC_AUTH_TOKEN

# 2. Clear ~/.claude.json cache
cat ~/.claude.json | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('customApiKeyResponses', {}))"

# 3. Check ~/.claude/settings.json
cat ~/.claude/settings.json | grep -A2 '"env"'

Fix: Remove hardcoded values from settings.json:

python3 -c "
import json
with open('/home/aptop/.claude/settings.json') as f:
d = json.load(f)
d['env'].pop('ANTHROPIC_API_KEY', None)
d['env'].pop('HTTPS_PROXY', None)
d['env'].pop('HTTP_PROXY', None)
with open('/home/aptop/.claude/settings.json', 'w') as f:
json.dump(d, f, indent=2)
"

For ~/.claude.json, manually edit the file to remove stale entries from customApiKeyResponses.approved.

Important Notes

  • Firewall Fix

    • If your Clash port is not 7897, replace it with your actual port โ€” the key is fixing the firewall interface, not the port
    • WSL updates or major Windows updates may reset the virtual NIC config; re-run the same command if the issue recurs
    • Windows 10 does not support WSL2's mirrored networking mode (only Windows 11 23H2+), do not try this direction
  • Dynamic IP

    • Always use dynamic IP detection in .bashrc โ€” never hardcode the host IP
    • The DNS server IP in /etc/resolv.conf is stable across WSL restarts
  • Config Cache

    • After clearing cached keys, restart Claude Code to apply changes
    • If auth still fails, check all three sources: environment variables, ~/.claude.json, and ~/.claude/settings.json

Troubleshooting Checklist (For Future Reference)โ€‹

  1. echo $ANTHROPIC_API_KEY $ANTHROPIC_AUTH_TOKEN โ€” confirm if both exist (conflict)
  2. cat ~/.claude.json | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('customApiKeyResponses', {}))" โ€” check cached keys
  3. cat ~/.claude/settings.json | grep -A2 '"env"' โ€” check for hardcoded env vars
  4. curl https://open.bigmodel.cn โ€” confirm GLM API is accessible

Dead Ends: 5 Directions Ruled Outโ€‹

For anyone currently troubleshooting, here are the paths already confirmed as dead ends:

#DirectionResultReason
1Proxy environment variablesRuled out.bashrc unset/export pattern is by design for model switching
2Clash Allow LAN not enabledRuled outAllow LAN is on, listening on 0.0.0.0:7897, localhost works
3Firewall port ruleRuled outAdded port 7897 inbound rule, still blocked โ€” NotApplicable
4Bind rule to InterfaceAliasRuled outSet-NetFirewallRule -InterfaceAlias "vEthernet (WSL)" had no effect
5Mirrored networking modeRuled outWindows 10 does not support it

The key insight: We kept trying to add rules, but the problem wasn't missing rules โ€” it was that rules don't apply to this interface at all.


Enable VSCode Copilot Agent Mode for Automated Programming

ยท 3 min read

TL;DRโ€‹

VSCode Copilot Agent Mode is an experimental feature that lets AI automatically execute multi-step tasks (including editing files and running terminal commands). Enable it by adding "github.copilot.chat.agent.enabled": true to your settings.json. Perfect for repetitive refactoring and batch file modifications.

Problemโ€‹

Traditional Copilot Chat only suggests code snippets, requiring you to:

  1. Manually copy the code
  2. Switch to the target file
  3. Paste and adjust
  4. Repeat for each change

This workflow becomes extremely inefficient when modifying multiple files.

Root Causeโ€‹

Copilot's Ask Mode is designed as a "suggester": it outputs code but doesn't execute actions. This is a safety feature, but for developers who trust AI, it adds significant manual overhead.

Agent Mode acts as an "executor": AI can directly edit files and run commands, enabling true automated programming.

Solutionโ€‹

1. Enable Agent Modeโ€‹

Add to VSCode settings.json:

{
"github.copilot.chat.agent.enabled": true
}

Or search for @id:github.copilot.chat.agent.enabled in Settings and check the box.

2. Switch to Agent Modeโ€‹

In the Copilot Chat panel, click the mode dropdown and switch from "Ask" to "Agent":

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Ask โ–ผ โ”‚ Agent โ–ผ โ”‚ Edit โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

3. Usage Examplesโ€‹

Scenario: Batch Rename Function

Rename getUserName to fetchUserProfile in all files under src/utils

Agent Mode will automatically:

  1. Scan the src/utils directory
  2. Find all files containing getUserName
  3. Modify each file and save

Scenario: Add TypeScript Types

Add return type annotations to all exported functions in src/api/*.ts

4. Tool Permission Controlโ€‹

Agent Mode requests confirmation before executing sensitive operations. Adjust in settings:

{
"github.copilot.chat.agent.autoToolConfirmation": {
"readFile": true, // Auto-allow file reading
"editFile": false, // Require confirmation for edits
"runInTerminal": false // Require confirmation for commands
}
}

5. Available Toolsโ€‹

Agent Mode can call these tools:

ToolFunction
readFileRead file contents
editFileEdit files
createFileCreate new files
deleteFileDelete files
runInTerminalExecute terminal commands
listDirectoryList directory contents
searchSearch code

FAQโ€‹

Q: What's the difference between Agent Mode and Ask Mode?โ€‹

Ask Mode only suggests code, requiring manual copy-paste; Agent Mode can directly execute file edits and terminal commands for automation.

Q: Is Agent Mode safe?โ€‹

Agent Mode requests confirmation before sensitive operations (like deleting files or running commands). Always use it in version-controlled repositories for easy rollback.

Q: Why can't I find the Agent Mode option?โ€‹

Ensure you have the latest Copilot Chat extension (v0.15+) and enable github.copilot.chat.agent.enabled in settings.

Q: What terminal commands can Agent Mode execute?โ€‹

Theoretically any command, but stick to safe development commands (like npm install, npm run build). Avoid high-risk operations like deletions or deployments.