pbakaus/impeccable · error

Update failed: {e}

Error message

Update failed: {e}

What it means

Inside the post-download update flow, errors from the update steps (e.g. comparing versions, copying skills, deciding hook installation) arrive as Flow::Throw(e) and are printed as 'Update failed: {e}' with exit 1. This is the generic error arm of the update result match.

Source

Thrown at crates/skills/src/commands.rs:842

                copy_provider_hooks(&sys, &tmp_dir, &root, &copy_providers, force, None).map_err(Flow::Throw)?
            } else {
                Vec::new()
            };
            Ok(hook_targets)
        })();
        util::rm_rf(&tmp_dir);
        return match outcome {
            Ok(hook_targets) => {
                let v = sys.get_skills_version(&root, scope);
                out(io, &format!("Skills are up to date{}.", version_suffix(&v)));
                if !hook_targets.is_empty() {
                    out(io, &format!("Installed hooks into: {}", hook_targets.join(", ")));
                }
                out(io, "Nothing else to do.");
                Err(Flow::Exit(0))
            }
            Err(Flow::Throw(e)) => {
                err(io, &format!("Update failed: {e}"));
                Err(Flow::Exit(1))
            }
            // JS: the try/catch around decideHookInstall swallows the prompt
            // abort too, printing its message.
            Err(Flow::Abort) => {
                err(io, "Update failed: Aborted.");
                Err(Flow::Exit(1))
            }
            Err(other) => Err(other),
        };
    }

    out(io, &format!("Found skills in: {}", copy_providers.join(", ")));

    if !yes {
        let ans = prompt.ask(io, &format!("Update skills in {} provider folder(s)? (Y/n) ", copy_providers.len()))?;
        if ans == "n" || ans == "no" {
            util::rm_rf(&tmp_dir);

View on GitHub (pinned to 2bc2879276)

Solutions

  1. Inspect the inner `{e}` message for the root cause (permissions, missing files).
  2. Ensure target harness folders are writable before running update.
  3. Run with --no-hooks to isolate hook-install failures.
  4. As a last resort, delete the skills folder and run `impeccable install` fresh.

Example fix

// before
impeccable update  # Update failed: Permission denied writing .cursor/skills
// after
chmod -R u+w .cursor && impeccable update --providers=.cursor
Defensive patterns

Strategy: try-catch

Validate before calling

for d in .claude .cursor; do [ -w "$d" ] || echo "$d not writable"; done

Try / catch

if ! impeccable update --providers=.claude; then
  echo "update failed ($?) — falling back to fresh install"
  impeccable install --providers=.claude --force
fi

Prevention

When it happens

Trigger: `update` when any inner step returns Flow::Throw: file copy failures while updating skills, version-check IO errors, or errors from hook installation logic.

Common situations: Read-only or partially locked harness folders during overwrite; filesystem errors mid-update; corrupted existing installation state that cannot be reconciled.

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 pbakaus/impeccable@2bc2879276 (2026-09-08). Data as JSON: /api/errors/02695642ea39c891. Report an issue: GitHub.