YeonGyu-Kim d49a75cad5 fix(#130b): enrich filesystem I/O errors with operation + path context
## What Was Broken (ROADMAP #130b, filed cycle #47)

In a fresh workspace, running:

    claw export latest --output /private/nonexistent/path/file.jsonl --output-format json

produced:

    {"error":"No such file or directory (os error 2)","hint":null,"kind":"unknown","type":"error"}

This violates the typed-error contract:
- Error message is a raw errno string with zero context
- Does not mention the operation that failed (export)
- Does not mention the target path
- Classifier defaults to "unknown" even though the code path knows
  this is a filesystem I/O error

## Root Cause (Traced)

run_export() at main.rs:~6915 does:

    fs::write(path, &markdown)?;

When this fails:
1. io::Error propagates via ? to main()
2. Converted to string via .to_string() in error handler
3. classify_error_kind() cannot match "os error" or "No such file"
4. Defaults to "kind": "unknown"

The information is there at the source (operation name, target path,
io::ErrorKind) but lost at the propagation boundary.

## What This Fix Does

Three changes:

1. **New helper: contextualize_io_error()** (main.rs:~260)
   Wraps an io::Error with operation name + target path into a
   recognizable message format:

       "{operation} failed: {target} ({error})"

2. **Classifier branch added** (classify_error_kind at main.rs:~270)
   Recognizes the new format and classifies as "filesystem_io_error":

       else if message.contains("export failed:") ||
               message.contains("diff failed:") ||
               message.contains("config failed:") {
           "filesystem_io_error"
       }

3. **run_export() wired** (main.rs:~6915)
   fs::write() call now uses .map_err() to enrich io::Error:

       fs::write(path, &markdown).map_err(|e| -> Box<dyn std::error::Error> {
           contextualize_io_error("export", &path.display().to_string(), e).into()
       })?;

## Dogfood Verification

Before fix:

    {"error":"No such file or directory (os error 2)","kind":"unknown","type":"error"}

After fix:

    {"error":"export failed: /private/nonexistent/path/file.jsonl (No such file or directory (os error 2))","kind":"filesystem_io_error","type":"error"}

The envelope now tells downstream claws:
- WHAT operation failed (export)
- WHERE it failed (the path)
- WHAT KIND of failure (filesystem_io_error)
- The original errno detail preserved for diagnosis

## Non-Regression Verification

- Successful export still works (emits "kind": "export" envelope as before)
- Session not found error still emits "session_not_found" (not filesystem)
- missing_credentials still works correctly
- cli_parse still works correctly
- All 180 binary tests pass
- All 466 library tests pass
- All 95 compat-harness tests pass

## Regression Tests Added

Inside the main CliAction test function:

- "export failed:" pattern classifies as "filesystem_io_error" (not "unknown")
- "diff failed:" pattern classifies as "filesystem_io_error"
- "config failed:" pattern classifies as "filesystem_io_error"
- contextualize_io_error() produces a message containing operation name
- contextualize_io_error() produces a message containing target path
- Messages produced by contextualize_io_error() are classifier-recognizable

## Scope

This is the minimum viable fix: enrich export's fs::write with context.
Future work (filed as part of #130b scope): apply same pattern to
other filesystem operations (diff, plugins, config fs reads, session
store writes, etc.). Each application is a copy-paste of the same
helper pattern.

## Pattern

Follows #145 (plugins parser interception), #248-249 (arm-level leak
templates). Helper + classifier + call site wiring. Minimal diff,
maximum observability gain.

## Related

- Closes #130b (filesystem error context preservation)
- Stacks on top of #251 (dispatch-order fix) — same worktree branch
- Ground truth for future #130 broader sweep (other io::Error sites)
2026-04-23 01:40:07 +09:00
2026-04-07 15:52:30 +09:00

Claw Code

ultraworkers/claw-code · Usage · Error Handling · Rust workspace · Parity · Roadmap · UltraWorkers Discord

Star history for ultraworkers/claw-code

Claw Code

Claw Code is the public Rust implementation of the claw CLI agent harness. The canonical implementation lives in rust/, and the current source of truth for this repository is ultraworkers/claw-code.

Important

Start with USAGE.md for build, auth, CLI, session, and parity-harness workflows. Make claw doctor your first health check after building, use rust/README.md for crate-level details, read PARITY.md for the current Rust-port checkpoint, and see docs/container.md for the container-first workflow.

ACP / Zed status: claw-code does not ship an ACP/Zed daemon entrypoint yet. Run claw acp (or claw --acp) for the current status instead of guessing from source layout; claw acp serve is currently a discoverability alias only, and real ACP support remains tracked separately in ROADMAP.md.

Current repository shape

  • rust/ — canonical Rust workspace and the claw CLI binary
  • USAGE.md — task-oriented usage guide for the current product surface
  • ERROR_HANDLING.md — unified error-handling pattern for orchestration code
  • PARITY.md — Rust-port parity status and migration notes
  • ROADMAP.md — active roadmap and cleanup backlog
  • PHILOSOPHY.md — project intent and system-design framing
  • SCHEMAS.md — JSON protocol contract (Python harness reference)
  • src/ + tests/ — companion Python/reference workspace and audit helpers; not the primary runtime surface

Quick start

Note

[!WARNING] cargo install claw-code installs the wrong thing. The claw-code crate on crates.io is a deprecated stub that places claw-code-deprecated.exe — not claw. Running it only prints "claw-code has been renamed to agent-code". Do not use cargo install claw-code. Either build from source (this repo) or install the upstream binary:

cargo install agent-code   # upstream binary — installs 'agent.exe' (Windows) / 'agent' (Unix), NOT 'agent-code'

This repo (ultraworkers/claw-code) is build-from-source only — follow the steps below.

# 1. Clone and build
git clone https://github.com/ultraworkers/claw-code
cd claw-code/rust
cargo build --workspace

# 2. Set your API key (Anthropic API key — not a Claude subscription)
export ANTHROPIC_API_KEY="sk-ant-..."

# 3. Verify everything is wired correctly
./target/debug/claw doctor

# 4. Run a prompt
./target/debug/claw prompt "say hello"

Note

Windows (PowerShell): the binary is claw.exe, not claw. Use .\target\debug\claw.exe or run cargo run -- prompt "say hello" to skip the path lookup.

Windows setup

PowerShell is a supported Windows path. Use whichever shell works for you. The common onboarding issues on Windows are:

  1. Install Rust first — download from https://rustup.rs/ and run the installer. Close and reopen your terminal when it finishes.
  2. Verify Rust is on PATH:
    cargo --version
    
    If this fails, reopen your terminal or run the PATH setup from the Rust installer output, then retry.
  3. Clone and build (works in PowerShell, Git Bash, or WSL):
    git clone https://github.com/ultraworkers/claw-code
    cd claw-code/rust
    cargo build --workspace
    
  4. Run (PowerShell — note .exe and backslash):
    $env:ANTHROPIC_API_KEY = "sk-ant-..."
    .\target\debug\claw.exe prompt "say hello"
    

Git Bash / WSL are optional alternatives, not requirements. If you prefer bash-style paths (/c/Users/you/... instead of C:\Users\you\...), Git Bash (ships with Git for Windows) works well. In Git Bash, the MINGW64 prompt is expected and normal — not a broken install.

Post-build: locate the binary and verify

After running cargo build --workspace, the claw binary is built but not automatically installed to your system. Here's where to find it and how to verify the build succeeded.

Binary location

After cargo build --workspace in claw-code/rust/:

Debug build (default, faster compile):

  • macOS/Linux: rust/target/debug/claw
  • Windows: rust/target/debug/claw.exe

Release build (optimized, slower compile):

  • macOS/Linux: rust/target/release/claw
  • Windows: rust/target/release/claw.exe

If you ran cargo build without --release, the binary is in the debug/ folder.

Verify the build succeeded

Test the binary directly using its path:

# macOS/Linux (debug build)
./rust/target/debug/claw --help
./rust/target/debug/claw doctor

# Windows PowerShell (debug build)
.\rust\target\debug\claw.exe --help
.\rust\target\debug\claw.exe doctor

If these commands succeed, the build is working. claw doctor is your first health check — it validates your API key, model access, and tool configuration.

Optional: Add to PATH

If you want to run claw from any directory without the full path, choose one of these approaches:

Option 1: Symlink (macOS/Linux)

ln -s $(pwd)/rust/target/debug/claw /usr/local/bin/claw

Then reload your shell and test:

claw --help

Option 2: Use cargo install (all platforms)

Build and install to Cargo's default location (~/.cargo/bin/, which is usually on PATH):

# From the claw-code/rust/ directory
cargo install --path . --force

# Then from anywhere
claw --help

Option 3: Update shell profile (bash/zsh)

Add this line to ~/.bashrc or ~/.zshrc:

export PATH="$(pwd)/rust/target/debug:$PATH"

Reload your shell:

source ~/.bashrc  # or source ~/.zshrc
claw --help

Troubleshooting

  • "command not found: claw" — The binary is in rust/target/debug/claw, but it's not on your PATH. Use the full path ./rust/target/debug/claw or symlink/install as above.
  • "permission denied" — On macOS/Linux, you may need chmod +x rust/target/debug/claw if the executable bit isn't set (rare).
  • Debug vs. release — If the build is slow, you're in debug mode (default). Add --release to cargo build for faster runtime, but the build itself will take 510 minutes.

Note

Auth: claw requires an API key (ANTHROPIC_API_KEY, OPENAI_API_KEY, etc.) — Claude subscription login is not a supported auth path.

Run the workspace test suite after verifying the binary works:

cd rust
cargo test --workspace

Documentation map

Ecosystem

Claw Code is built in the open alongside the broader UltraWorkers toolchain:

Ownership / affiliation disclaimer

  • This repository does not claim ownership of the original Claude Code source material.
  • This repository is not affiliated with, endorsed by, or maintained by Anthropic.
Description
The repo is finally unlocked. enjoy the party! The fastest repo in history to surpass 100K stars . Join Discord: https://discord.gg/5TUQKqFWd Built in Rust using oh-my-codex.
Readme 36 MiB
Languages
Rust 96.4%
Python 3.2%
Shell 0.4%