stablyai/orca · error
Targeted update changed the non-targeted control topology
Error message
Targeted update changed the non-targeted control topology
What it means
Third isolation rail for the control skill in symlink shape: after a targeted update, lstat(controlProvider) must still report a symbolic link. If the targeted update replaced the control provider symlink with a copy (or vice versa), topology changed and the throw fires.
Source
Thrown at config/scripts/verify-skill-update-roundtrip.mjs:245
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
- On Windows, ensure the runner has symlink privilege (Developer Mode or admin) so the control symlink is created and preserved.
- Diff lstat of controlProvider before/after to see if topology flipped.
- File a CLI bug: a targeted update must not alter non-target topology.
- Pin a known-good CLI version.
Defensive patterns
Strategy: validation
Validate before calling
// On Windows, refuse to run shape=symlink unless symlink privilege is available:
if (process.platform === 'win32' && shape === 'symlink') {
try {
const probe = path.join(sandbox, 'probe')
await symlink(targetName, probe); await rm(probe)
} catch {
throw new Error('Windows runner lacks symlink privilege; cannot exercise shape=symlink')
}
} Prevention
- On Windows CI, enable Developer Mode or run as admin so symlinks are preserved.
- Treat any topology flip on a non-target placement after a targeted update as a CLI regression.
- Pin the CLI version under test.
When it happens
Trigger: A targeted update that normalizes topology across all placements (e.g. converts all symlinks to copies) instead of only the target; symlink shape running on a platform/filesystem that silently resolves symlinks on write.
Common situations: CLI regression that re-homogenizes topology on update; Windows without symlink privilege causing the placement to fall back to copy; filesystem that doesn't preserve symlinks.
Related errors
- ${targetName} provider alias was replaced with an independen
- Targeted update changed the non-targeted control skill
- Targeted update changed the non-targeted control provider pl
- ${targetName} provider alias did not converge with the canon
- Unsupported packaged node-pty Windows architecture: ${archit
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/ce0f47ffefd58c13.
Report an issue: GitHub.