coleam00/Archon · error
Failed to move extracted web UI from ${tmpDir} to ${targetDi
Error message
Failed to move extracted web UI from ${tmpDir} to ${targetDir}: ${toError(err).message} What it means
downloadWebDist stages the extracted web UI in a temp dir and then atomically renames it into the target directory; if renameSync throws, cleanupAndThrow removes the temp dir and raises this error wrapping the OS message. renameSync fails across filesystems (EXDEV) or when the destination can't be created/replaced. The atomic move guarantees the server never sees a half-installed web UI.
Source
Thrown at packages/cli/src/commands/serve.ts:272
}
} finally {
rmSync(tarballPath, { force: true });
}
// Verify extraction produced expected layout
if (!existsSync(`${tmpDir}/index.html`)) {
cleanupAndThrow(
tmpDir,
'Extraction produced unexpected layout — index.html not found in extracted dir'
);
}
// Atomic move into place
mkdirSync(dirname(targetDir), { recursive: true });
try {
renameSync(tmpDir, targetDir);
} catch (err) {
cleanupAndThrow(
tmpDir,
`Failed to move extracted web UI from ${tmpDir} to ${targetDir}: ${toError(err).message}`
);
}
// Closes the last phase: staged-archive removal, layout check, and the rename
// of a freshly written tree — all after-tar filesystem work.
log.info(
{ targetDir, durationMs: Math.round(performance.now() - extractionEndedAt) },
'web_dist.installed'
);
console.log(`Extracted to ${targetDir}`);
}
function cleanupAndThrow(tmpDir: string, message: string): never {
rmSync(tmpDir, { recursive: true, force: true });
throw new Error(message);
}
View on GitHub (pinned to 0773b97458)
Solutions
- Read the wrapped OS message: EXDEV means set TMPDIR to a directory on the same filesystem as the installation, or copy-then-rename instead of rename.
- Remove/repair a leftover target directory from a prior failed install (stop the server first), then re-run serve.
- Fix permissions on the installation parent directory so mkdir/rename can succeed.
- On Windows, stop other processes locking the target path before retrying.
Example fix
// before
renameSync(tmpDir, targetDir); // throws EXDEV when tmp and target are different filesystems
// after
try {
renameSync(tmpDir, targetDir);
} catch (err) {
if ((err as NodeJS.ErrnoException).code === 'EXDEV') {
cpSync(tmpDir, targetDir, { recursive: true });
rmSync(tmpDir, { recursive: true, force: true });
} else throw err;
} Defensive patterns
Strategy: try-catch
Validate before calling
import { statSync } from 'node:fs';
const tmpDev = statSync(tmpDir).dev;
const targetDev = statSync(dirname(targetDir)).dev;
if (tmpDev !== targetDev) {
throw new Error(`rename would fail (EXDEV): TMPDIR (${tmpDir}) and target (${targetDir}) are on different filesystems; set TMPDIR to ${dirname(targetDir)}`);
}
if (existsSync(targetDir)) {
throw new Error(`Target ${targetDir} already exists; stop the server and remove it before upgrading`);
} Try / catch
try {
await serveCommand();
} catch (err) {
if (err instanceof Error && err.message.startsWith('Failed to move extracted web UI')) {
if (err.message.includes('EXDEV') || err.message.includes('cross-device')) {
// set TMPDIR to a directory on the same filesystem as the install, retry
} else if (err.message.includes('EBUSY') || err.message.includes('EPERM')) {
// stop processes locking the target (esp. Windows), retry
}
} else throw err;
} Prevention
- Set TMPDIR to the same filesystem/volume as the archon installation.
- Stop the running server before upgrading the web UI so the target isn't locked.
- Clean leftover target directories from failed installs before retrying.
- Keep the install prefix user-writable (avoid root-owned installs for user-run servers).
When it happens
Trigger: serveCommand -> downloadWebDist calls renameSync(tmpDir, targetDir) and it throws: temp dir and target on different filesystems (EXDEV), target path's parent not creatable (permissions), target existing as a non-empty dir/file that can't be replaced, or the target locked by a running process (EBUSY, Windows).
Common situations: TMPDIR on tmpfs while the install lives on the root filesystem (classic cross-device rename); read-only install prefix; leftover corrupt target dir from a previous failed install; another archon process holding the target open on Windows.
Related errors
- tar extraction failed (exit ${exitCode}): ${details}
- ENOENT
- EACCES
- Failed to read version: ${err.message}
- Failed to start detached workflow child (executable: ${cmd[0
AI-assisted analysis of coleam00/Archon@0773b97458 (2026-09-01).
Data as JSON: /api/errors/1b26091149d5fbcb.
Report an issue: GitHub.