stablyai/orca · error

Targeted update changed the non-targeted control provider pl

Error message

Targeted update changed the non-targeted control provider placement

What it means

Companion to 293: a targeted update must not change the control skill's provider placement either. The script hashes realpath(controlProvider) after the update and compares to controlProviderBefore; a mismatch means the targeted update rewrote the control provider placement it should have left alone.

Source

Thrown at config/scripts/verify-skill-update-roundtrip.mjs:241

    targetProviderAfter !== currentSkill(targetName).packageDigest
  ) {
    throw new Error('Independent provider copy changed to an unexpected package identity')
  }
  if (shape === 'copy') {
    // Why: hosted 1.5.17 replaces copies with aliases while equivalent local runs
    // retain the copy. Both prove this input topology must remain ineligible.
    const outcome = targetProviderStat.isSymbolicLink()
      ? 'converged to an alias'
      : targetProviderAfter === targetProviderBefore
        ? 'remained a historical copy'
        : 'converged as a copy'
    console.log(`[skill-update-roundtrip] independent copy ${outcome}`)
  }
  if ((await packageDigestAt(controlCanonical)) !== controlBefore) {
    throw new Error('Targeted update changed the non-targeted control skill')
  }
  if ((await packageDigestAt(await realpath(controlProvider))) !== controlProviderBefore) {
    throw new Error('Targeted update changed the non-targeted control provider placement')
  }
  const controlProviderStat = await lstat(controlProvider)
  if (shape === 'symlink' && !controlProviderStat.isSymbolicLink()) {
    throw new Error('Targeted update changed the non-targeted control topology')
  }
} finally {
  await rm(sandbox, { recursive: true, force: true })
}

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Confirm the control provider placement is pinned in the lock fixture so it isn't eligible for update.
  2. Diff the control provider content/symlink target before and after.
  3. File a CLI bug: targeted updates must not touch non-target provider placements.
  4. Pin a known-good CLI version.
Defensive patterns

Strategy: validation

Validate before calling

// Mirror of 293 for the provider placement:
const controlProviderBefore = await packageDigestAt(await realpath(controlProvider))
// ... after update:
if ((await packageDigestAt(await realpath(controlProvider))) !== controlProviderBefore) {
  throw new Error('control provider placement drifted')
}

Prevention

When it happens

Trigger: Same scoping regression as 293 but manifesting at the provider (vendor) placement rather than the canonical skill dir; the control provider symlink got repointed; the control provider copy got its content rewritten.

Common situations: CLI regression updating all provider placements instead of just the target's; lock fixture not pinning the control provider; symlink repoint side effect of a global update.

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/f94ce52406c37935. Report an issue: GitHub.