Skip to content

Windows: ruler apply can fail with EPERM during native skills rename #412

@BartNetJS

Description

@BartNetJS

Summary

ruler apply on Windows can fail during native skills propagation with:

[ruler] EPERM: operation not permitted, rename '...\\skills.tmp-<timestamp>' -> '...\\skills'

This reproduces on @intellectronica/[email protected], which is also the latest npm version at the time of testing.

Reproduction

Project root contained a .ruler/skills directory and native agent folders including .claude.

Command:

ruler apply

Observed failure:

[ruler] Nested mode is experimental and may change in future releases.
[ruler] Skills are configured, but the following agents do not support native skills and will be skipped: Warp
[ruler] Skills support is experimental and behavior may change in future releases.
[ruler] EPERM: operation not permitted, rename 'C:\Users\...\Atlas\\.claude\\skills.tmp-1775568298919' -> 'C:\Users\...\Atlas\\.claude\\skills'

Isolation

ruler apply --skills false completes successfully, so the failure is isolated to the native skills propagation step.

The installed CLI implementation uses a direct fs.rename(tempDir, targetDir) after copying .ruler/skills to a temporary directory. On Windows this can lose a race with Defender or another filesystem lock and return EPERM.

Root cause

In the current release, skills propagation uses a direct rename with no retry and no fallback copy path.

Affected implementation area:

  • dist/core/SkillsProcessor.js
  • propagateSkillsForClaude
  • propagateSkillsForCodex
  • propagateSkillsForOpenCode
  • equivalent functions for other native-skills targets

Workarounds verified locally

  1. ruler apply --skills false succeeds.
  2. A local patch that wraps the final replace step with:
    • retry on EPERM, EBUSY, and ENOTEMPTY
    • fallback to copy-and-remove when rename still fails

After that local patch, plain ruler apply succeeded.

Suggested fix

In SkillsProcessor, replace the direct fs.rename(tempDir, targetDir) with a helper that:

  1. retries transient Windows rename errors
  2. falls back to copy-and-remove if the rename keeps failing
  3. keeps temp-directory cleanup in the existing error path

That should preserve the current behavior on normal filesystems while making skills propagation reliable on Windows.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions