# How to Make CodeWhale Install Failures Non-Fatal

> Learn how to make CodeWhale install failures non-fatal in your repository. Continue processing and get a full summary even if some skills fail. Fix installation issues efficiently.

- Repository: [Hunter Bown/CodeWhale](https://github.com/Hmbown/CodeWhale)
- Tags: how-to-guide
- Published: 2026-06-02

---

**CodeWhale treats individual skill installation failures as non-fatal by default, recording errors while continuing to process remaining items and reporting a comprehensive summary upon completion rather than aborting the entire operation.**

CodeWhale is a Rust-based terminal user interface (TUI) application designed for robust skill management. When syncing skills from the registry, the application implements a deliberate error-handling strategy that ensures single-package failures do not interrupt your entire workflow. Understanding this non-fatal architecture helps you leverage the tool's resilience when managing complex skill dependencies.

## The Non-Fatal Design Philosophy

According to the Hmbown/CodeWhale source code, the installer architecture embeds a specific design pattern where failures are explicitly treated as **non-fatal events**. This approach appears throughout the Rust codebase, with inline comments stating "Failures are non-fatal" accompanying sections that deliberately swallow errors after logging warnings. This pattern ensures network-gated installations and registry syncs remain stable even when individual skills cannot be fetched.

## Core Implementation: SkillSyncOutcome Enum

The foundation of non-fatal error handling resides in the `SkillSyncOutcome` enumeration defined in [`crates/tui/src/skills/install.rs`](https://github.com/Hmbown/CodeWhale/blob/main/crates/tui/src/skills/install.rs).

### Defining Permissible Failure States

The enum at lines 17-26 categorizes all possible per-skill outcomes without triggering program termination:

- `Failed { name, reason }` — Captures download or parsing errors
- `Denied { ... }` — Records permission or policy violations  
- `NeedsApproval { ... }` — Tracks skills requiring network consent

Each variant merely increments internal counters rather than propagating panics, allowing the sync loop to continue processing subsequent skills.

### The Sync Loop Error Containment

Within the same file (lines 67-70), the `sync_registry` function implements the actual download logic. When a skill download encounters an error, the function returns `SkillSyncOutcome::Failed` instead of propagating the error upward through the call stack:

```rust
// When download fails, return Failed variant instead of Err
SkillSyncOutcome::Failed { 
    name: skill_name.to_string(), 
    reason: error.to_string() 
}

```

This containment strategy ensures that a single `Err` response does not bubble up to abort the entire registry synchronization.

## CLI Aggregation and Safe Defaults

The command-line interface in [`crates/tui/src/commands/skills.rs`](https://github.com/Hmbown/CodeWhale/blob/main/crates/tui/src/commands/skills.rs) orchestrates the non-fatal workflow through two key mechanisms.

### The /skills sync Command

Lines 21-45 implement the `/skills sync` command, which aggregates individual `SkillSyncOutcome` results into a final report. The command constructs a summary table displaying:

- `[+]` Downloaded skills
- `[=]` Up-to-date skills  
- `[!]` Failed skills
- `[?]` Skills needing approval

The implementation only aborts on **registry-level** failures (such as when the entire index cannot be fetched), while treating individual skill failures as data points for the final summary.

### Defensive Configuration Loading

Lines 69-75 contain the `installer_settings` helper function, which loads user configuration safely. If the configuration file cannot be parsed, the function falls back to default values rather than panicking, ensuring the installation process proceeds with sensible defaults:

```rust
let settings = installer_settings().unwrap_or_else(|_| {
    warn!("Using default installer settings");
    InstallerSettings::default()
});

```

## Working with Non-Fatal Failures in Practice

Since CodeWhale install failures are non-fatal by design, you do not need to enable special flags. However, you can implement specific workflows to handle these soft errors.

### Interpreting Sync Output

Run a standard skill sync to see the non-fatal reporting in action:

```bash
$ codewhale skill sync
Registry sync complete.

  [+] sql-explorer — downloaded to /home/user/.codewhale/cache/skills/sql-explorer/
  [=] lorem-ipsum  — already up to date
  [!] broken-skill — failed: 404 Not Found
  [?] gated-skill — needs approval for example.com (run `/network allow example.com` then retry)

4 skill(s) processed: 1 downloaded, 1 up-to-date, 2 failed.

```

The process completed successfully despite two failures, and the exit code remains non-fatal.

### Filtering for Failed Skills

When automating CI/CD pipelines, extract failed items using standard Unix tools:

```bash
codewhale skill sync | grep '\[!\]'

```

### Retrying Specific Failures

To force a retry of a previously failed skill without re-syncing the entire registry:

```bash
codewhale skill install broken-skill --force

```

### Programmatic Error Handling

When integrating with the CodeWhale Rust API, handle outcomes individually:

```rust
match outcome {
    SkillSyncOutcome::Failed { name, reason } => {
        // Log the failure but continue processing other skills
        warn!("skill `{}` failed to install: {}", name, reason);
        // Optionally queue for retry or alert monitoring systems
    }
    SkillSyncOutcome::Downloaded { name, path } => {
        info!("Successfully installed {} to {:?}", name, path);
    }
    _ => {}
}

```

## Summary

- **SkillSyncOutcome enum** in [`crates/tui/src/skills/install.rs`](https://github.com/Hmbown/CodeWhale/blob/main/crates/tui/src/skills/install.rs) defines non-fatal failure categories that increment counters rather than aborting execution
- **sync_registry function** returns failure variants instead of propagating errors, maintaining the sync loop's continuity
- **`/skills sync` command** aggregates all outcomes into a summary table, only aborting on registry-level catastrophes
- **installer_settings** implements safe configuration loading with default fallbacks to prevent parse errors from crashing the install
- **No special configuration** is required—non-fatal behavior is the default operational mode across all skill installation workflows

## Frequently Asked Questions

### Are CodeWhale install failures fatal by default?

No, install failures are explicitly non-fatal by design. The system records the error, continues processing remaining skills, and reports the failure in the final summary without aborting the entire operation. This behavior is hardcoded in the `sync_registry` function and requires no user configuration to enable.

### How can I identify which specific skills failed to install?

Failed skills appear in the sync output marked with `[!]` alongside the failure reason. You can filter the command output using `grep '\[!]'` to isolate failed entries, or parse the Rust API's `SkillSyncOutcome::Failed` variant programmatically to capture the `name` and `reason` fields for each failure.

### Can I force a retry of a specific skill that previously failed?

Yes. Use the `--force` flag with the individual install command: `codewhale skill install <skill-name> --force`. This bypasses caching and reattempts the download for that specific skill without requiring a full registry resync.

### What types of errors will cause CodeWhale to abort completely?

CodeWhale only treats **registry-level** failures as fatal, such as when the entire skill index cannot be fetched or when the network is completely unavailable. Individual skill download failures (404 errors, parsing errors, permission denials) are captured as `SkillSyncOutcome` variants and do not trigger program termination.