# Troubleshooting

Common issues and how to fix them.

## Authentication Errors

### "Token exchange failed"

**Cause:** The authorization code is invalid or expired.

**Fix:**
1. Codes expire quickly - use them immediately
2. Make sure you copied the entire code (including any `#state` suffix)
3. Try the OAuth flow again

```bash
rm ~/.porta/tokens.json
cargo run --bin provider-cli
```

### "Token refresh failed: 401"

**Cause:** Refresh token is invalid or revoked.

**Fix:** Delete tokens and re-authenticate:

```bash
rm ~/.porta/tokens.json
cargo run --bin provider-cli
```

### "This credential is only authorized for use with Claude Code"

**Cause:** The request doesn't match Claude Code's expected format.

**Fix:** Ensure:
1. System prompt starts with "You are Claude Code..."
2. `tools` array is included (even if empty)
3. Tool names are prefixed with `mcp_`
4. Correct headers are set (User-Agent, beta flags)

This should be handled automatically by `RequestTransformer`.

---

## API Errors

### "500 Internal Server Error"

**Cause:** Request format doesn't match expectations.

**Fix:** Check that your request includes:

```json
{
  "model": "claude-sonnet-4-20250514",
  "max_tokens": 1024,
  "system": "You are Claude Code, Anthropic's official CLI for Claude.",
  "tools": [],
  "messages": [...]
}
```

### "400 Bad Request"

**Cause:** Invalid JSON or missing required fields.

**Fix:** Validate your request body:

```rust
// Make sure it's valid JSON
let _: serde_json::Value = serde_json::from_str(body)?;
```

### "429 Too Many Requests"

**Cause:** Rate limit exceeded.

**Fix:** Wait and retry. Claude Pro/Max has usage limits.

---

## Build Errors

### "error[E0433]: failed to resolve: use of undeclared crate"

**Cause:** Missing dependency.

**Fix:** Check `Cargo.toml` has all dependencies:

```toml
[dependencies]
tokio = { version = "1", features = ["full"] }
reqwest = { version = "0.12", features = ["json", "stream"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
# ... etc
```

Then run:
```bash
cargo build
```

### "error: expected `;`" or similar syntax errors

**Cause:** Rust syntax error.

**Fix:** Check for:
- Missing semicolons at end of statements
- Mismatched braces `{}`
- Missing commas in struct fields

### "the trait `X` is not implemented for `Y`"

**Cause:** Type mismatch or missing trait implementation.

**Fix:** Common cases:
- Add `#[derive(Debug, Clone)]` to structs
- Use `.into()` or `.to_string()` for conversions
- Check function signatures match expected types

---

## Runtime Issues

### "Connection refused"

**Cause:** Network issue or firewall blocking.

**Fix:**
1. Check internet connection
2. Try: `curl https://api.anthropic.com/v1/messages`
3. Check firewall/proxy settings

### "Tokens file not found"

**Cause:** First run or tokens deleted.

**Fix:** This is normal - the OAuth flow will start automatically.

### "Permission denied" when saving tokens

**Cause:** Can't write to home directory.

**Fix:**
```bash
mkdir -p ~/.porta
chmod 755 ~/.porta
```

---

## Testing Issues

### Tests fail with network errors

**Cause:** Tests are trying to make real HTTP requests.

**Fix:** Mock the HTTP client or use `#[ignore]` for integration tests:

```rust
#[test]
#[ignore]  // Skip in normal test runs
fn test_real_api() {
    // ...
}
```

Run ignored tests explicitly:
```bash
cargo test -- --ignored
```

---

## Debug Tips

### Enable debug logging

```rust
// Add to Cargo.toml
[dependencies]
tracing = "0.1"
tracing-subscriber = "0.3"

// In main()
tracing_subscriber::fmt::init();
```

### Print request/response

```rust
let transformed = RequestTransformer::transform_request(body).unwrap();
println!("Transformed request: {}", transformed);

let response = client.messages(body).await?;
println!("Response: {}", response);
```

### Check token status

```rust
let tokens = client.tokens().await;
println!("Access token: {}...", &tokens.access_token[..20]);
println!("Expires at: {}", tokens.expires_at);
println!("Is expired: {}", tokens.is_expired());
```

### Inspect HTTP traffic

Use a proxy like mitmproxy to see actual requests:

```bash
# Install mitmproxy
brew install mitmproxy

# Run it
mitmproxy

# Set env var
export HTTPS_PROXY=http://localhost:8080

# Run your code
cargo run --bin provider-cli
```

---

## Getting Help

1. Check this troubleshooting guide
2. Read the [Architecture docs](./architecture.md)
3. Look at the [OAuth Flow docs](./oauth-flow.md)
4. Check the test files for examples
5. Open an issue with:
   - Error message
   - What you were trying to do
   - Relevant code snippet
