Yeachan-Heo/oh-my-codex · error · Error
[native-assets] unable to create cache root
Error message
[native-assets] unable to create cache root
What it means
The configured native cache root could not be created (or canonicalized) — canonicalCacheRoot returned undefined after attempting mkdir(recursive). Without a usable root, managed binary publication cannot proceed.
Source
Thrown at src/cli/native-assets.ts:620
if (!sameFile(lock.identity, reopened) || reopened.text !== lock.record) return { state: 'cleanup-failed' };
const current = await lstat(lock.path);
if (!sameFile(lock.identity, { dev: current.dev, ino: current.ino, size: current.size }) || !current.isFile() || current.nlink !== 1) return { state: 'cleanup-failed' };
await unlink(lock.path);
} catch (error) { return absent(error) ? undefined : { state: 'cleanup-failed' }; }
return undefined;
}
async function quarantineInvalid(path: string): Promise<void> {
try {
await lstat(path);
await rename(path, `${path}.quarantine.${uuid()}`);
} catch (error) { if (!absent(error)) throw error; }
}
async function publishManagedNativeBinary(source: string, destination: string, platform: NodeJS.Platform, env: NodeJS.ProcessEnv): Promise<string | undefined> {
const configuredRoot = resolveNativeCacheRoot(env);
const root = await canonicalCacheRoot(configuredRoot, true);
if (!root) throw new Error('[native-assets] unable to create cache root');
destination = canonicalDescendantPath(destination, configuredRoot, root);
await validateDescendant(destination, root, true);
const lock = await acquireCacheLock(destination, env);
const attempt = uuid();
const tempBinary = join(dirname(destination), `.${attempt}.tmp.bin`);
const tempSidecar = join(dirname(destination), `.${attempt}.tmp.sha256`);
const revalidatePublicationPaths = async (): Promise<void> => {
await validateDescendant(destination, root, false);
await validateDescendant(sidecarPath(destination), root, false);
await validateDescendant(lock.path, root, false);
await validateDescendant(tempBinary, root, false);
await validateDescendant(tempSidecar, root, false);
};
let primaryError: unknown;
try {
await revalidatePublicationPaths();
const existing = await inspectManagedNativeBinary(destination, env);
if (existing.state === 'verified') return existing.path;View on GitHub (pinned to 3ad79a8a6f)
Solutions
- Fix permissions/ownership of the cache root path (chown -R $(whoami)).
- Set the cache-root env override to a writable location (e.g. a tmpfs or project-local dir).
- In containers, ensure HOME and the cache dir are on a writable volume.
Example fix
# before: cache root /root/.cache/omx owned by root, running as app sudo chown -R app:app /root/.cache/omx # or: export OMX_NATIVE_CACHE_ROOT=/tmp/omx-cache # (use the library's documented override)
Defensive patterns
Strategy: validation
Validate before calling
import { accessSync, constants } from 'node:fs';
function cacheRootWritable(root: string): boolean { try { accessSync(root, constants.W_OK | constants.X_OK); return true; } catch { try { accessSync(require('node:path').dirname(root), constants.W_OK); return true; } catch { return false; } } } Try / catch
try { await hydrateNativeBinary(); } catch (e) { if (/unable to create cache root/.test(String(e))) { /* chown/chmod the cache dir or point env override at a writable path */ } throw e; } Prevention
- Ensure write access to the cache directory in containers
- Set the cache-root env override to a writable volume
- Avoid running hydration after sudo/root owned the cache dir
When it happens
Trigger: publishManagedNativeBinary when the cache root path is unwritable (EACCES), sits on a read-only mount, or its parent cannot be traversed; canonicalCacheRoot swallows absent errors but fails to produce a canonical root.
Common situations: Running as a user without write access to the default cache location (e.g. root-owned ~/.cache after sudo misuse); read-only container filesystems; XDG-style env overrides pointing to invalid paths.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- [native-assets] cache path escapes configured root
- [native-assets] cache descendant is unsafe: ${current}
- [native-assets] cache publication verification failed: ${fin
- [native-assets] cache publication verification failed for ${
- [omx] warning: failed to create notify fallback watcher stat
AI-assisted analysis of Yeachan-Heo/oh-my-codex@3ad79a8a6f (2026-08-27).
Data as JSON: /api/errors/a5fa11c6e4f0f99b.
Report an issue: GitHub.