iOfficeAI/AionUi · critical

spawn

spawn

Error message

aioncore startup directory preparation failed

What it means

Thrown by BackendLauncher.attemptStart with code 'spawn' when preparing the aioncore startup directories (log, cache, work dirs via ensureBackendStartupDirectory) raises an exception — typically because a directory path cannot be created due to permissions, a file existing where a directory is expected, a read-only filesystem, or an invalid path. The launcher sets status to 'error' and wraps the underlying filesystem error in a structured startup error.

Source

Thrown at packages/web-host/src/backend-launcher.ts:686

      local: true,
      parentPid: process.pid,
      logDir,
      workDir: dirs?.workDir,
      appVersion,
      isPackaged: this.appMeta.isPackaged,
      recoverCorruptedDatabase: launchFlags.recoverCorruptedDatabase === true,
    });
    console.log(`[aioncore] starting: ${binaryPath} ${args.join(' ')}`);

    try {
      ensureBackendStartupDirectory(dbPath);
      ensureBackendStartupDirectory(logDir);
      ensureBackendStartupDirectory(dirs?.cacheDir);
      ensureBackendStartupDirectory(dirs?.workDir);
      ensureBackendStartupDirectory(dirs?.logDir);
    } catch (error) {
      this._status = 'error';
      throw makeStartupError('spawn', 'aioncore startup directory preparation failed', error);
    }

    try {
      this.childProcess = spawn(binaryPath, args, {
        stdio: ['pipe', 'pipe', 'pipe'],
        env: buildSpawnEnv(dirs),
        cwd: dirs?.workDir ?? dbPath,
        detached: process.platform !== 'win32',
      });
    } catch (error) {
      this._status = 'error';
      throw makeStartupError('spawn', 'aioncore process spawn threw before startup', error);
    }

    this.childProcess.stdin?.end();

    backendPid = this.childProcess.pid;
    const pid = backendPid;

View on GitHub (pinned to 711aa0550e)

Solutions

  1. Inspect the wrapped `error.cause` — it contains the exact fs error and offending path.
  2. Verify each configured dir (cacheDir, workDir, logDir) is writable by the process user: mkdir -p && touch test.
  3. Fix mounts/permissions (chmod/chown, correct Docker volume) or point the dirs at a writable location via config.
  4. Remove a stale regular file occupying a required directory path.
  5. Ensure HOME/env is set so default dir resolution doesn't produce an invalid path.

Example fix

// before
const launcher = new BackendLauncher({ cacheDir: '/opt/aionui/cache' }); // EACCES
await launcher.start(); // throws 'startup directory preparation failed'

// after
const launcher = new BackendLauncher({ cacheDir: path.join(os.homedir(), '.aionui', 'cache') });
await fs.mkdir(cacheDir, { recursive: true }); // preflight
await launcher.start();
Defensive patterns

Strategy: validation

Validate before calling

import fs from 'node:fs';
for (const dir of [logDir, cacheDir, workDir].filter(Boolean) as string[]) {
  fs.mkdirSync(dir, { recursive: true }); // throws early with the offending path
  fs.accessSync(dir, fs.constants.W_OK);
}

Try / catch

try {
  await launcher.start();
} catch (e) {
  if (isStartupError(e) && e.code === 'spawn' && /directory preparation/.test(e.message)) {
    const cause = e.cause; // fs error: EACCES / EROFS / EEXIST with real path
    throw new Error(`Fix permissions for startup dirs: ${cause?.path ?? cause?.message}`);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling start() when any of logDir/cacheDir/workDir/dbPath-derived directories is uncreatable: EACCES/EEXIST-not-a-directory/EROFS/ENOENT (missing parent), or an invalid path string.

Common situations: Running as a user without write access to the configured data dir; container with a read-only or wrongly-mounted volume; config pointing cacheDir at an existing file; disk full; path with invalid characters on Windows; HOME unset in a systemd/docker environment.

Related errors


AI-assisted analysis of iOfficeAI/AionUi@711aa0550e (2026-08-28). Data as JSON: /api/errors/30580f0c992bc898. Report an issue: GitHub.