rtk-ai/rtk · error

Failed to uninstall RTK from one or more Droid hook files

Error message

Failed to uninstall RTK from one or more Droid hook files:
  - {}

What it means

During `rtk init` uninstall, RTK tries to remove its hooks from every known Droid hook file. If removal from any candidate file fails, all per-file errors are collected and returned together as this aggregated anyhow error.

Solutions

  1. Read the per-file messages after the header to see which files failed and why.
  2. Fix permissions on the listed files (chown/chmod) and re-run the uninstall.
  3. Manually remove the RTK hook entries from the failing JSON hook files if automated removal keeps failing.
  4. Restore the hook files to a valid state (reinstall/reconfigure Droid) and retry.

Example fix

// before
$ rtk init --uninstall  # fails: permission denied
// after
chmod u+w ~/.droid/hooks.json && rtk init --uninstall
Defensive patterns

Strategy: try-catch

Validate before calling

import json, os
for p in ['~/.droid/hooks.json']:
    path = os.path.expanduser(p)
    if not os.access(path, os.W_OK):
        raise PermissionError(f'{path} is not writable')
    json.load(open(path))  # must be valid JSON for hook removal

Try / catch

match rtk_uninstall_droid() {
    Err(e) if e.to_string().starts_with("Failed to uninstall RTK from one or more Droid hook files") => {
        // parse per-file errors, fix permissions/JSON, retry
    }
    other => other,
}

Prevention

When it happens

Trigger: Running the Droid uninstall path when one or more hook files cannot be processed: unreadable file, permission denied on write, malformed JSON that prevents hook removal, or the file path being a directory/symlink target that is missing.

Common situations: Hook files owned by another user or made read-only; partial/corrupt Droid config after a failed upgrade; files manually edited so the RTK hook JSON no longer matches what uninstall expects.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of rtk-ai/rtk@0924356b4c (2026-09-19). Data as JSON: /api/errors/5b04db12cb259e4f. Report an issue: GitHub.

Appendix: source

Thrown at src/hooks/init.rs:3745

    }
    Ok(())
}

fn uninstall_droid_at(droid_dir: &Path, ctx: InitContext) -> Result<Vec<String>> {
    let mut removed = Vec::new();
    let mut errors = Vec::new();
    for candidate in droid_hook_file_candidates(droid_dir) {
        match remove_droid_hook_from_file(&candidate, ctx) {
            Ok(true) => {
                removed.push(format!("Droid hook file: {}", candidate.path.display()));
            }
            Ok(false) => {}
            Err(error) => errors.push(format!("{}: {error:#}", candidate.path.display())),
        }
    }

    if !errors.is_empty() {
        return Err(anyhow::anyhow!(
            "Failed to uninstall RTK from one or more Droid hook files:\n  - {}",
            errors.join("\n  - ")
        ));
    }

    Ok(removed)
}

/// Strip the RTK entry from one Droid hook file. Returns true if the file
/// held an RTK entry (and was rewritten, unless dry-run).
fn remove_droid_hook_from_file(file: &DroidHookFile, ctx: InitContext) -> Result<bool> {
    let InitContext {
        verbose, dry_run, ..
    } = ctx;
    let path = &file.path;

    let mut root = match read_json_file(path)? {
        Some(v) => v,

View on GitHub (pinned to 0924356b4c)