{"record":{"id":"30580f0c992bc898","repo":"iOfficeAI/AionUi","slug":"spawn","errorCode":"spawn","errorMessage":"aioncore startup directory preparation failed","messagePattern":"aioncore startup directory preparation failed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"packages/web-host/src/backend-launcher.ts","lineNumber":686,"sourceCode":"      local: true,\n      parentPid: process.pid,\n      logDir,\n      workDir: dirs?.workDir,\n      appVersion,\n      isPackaged: this.appMeta.isPackaged,\n      recoverCorruptedDatabase: launchFlags.recoverCorruptedDatabase === true,\n    });\n    console.log(`[aioncore] starting: ${binaryPath} ${args.join(' ')}`);\n\n    try {\n      ensureBackendStartupDirectory(dbPath);\n      ensureBackendStartupDirectory(logDir);\n      ensureBackendStartupDirectory(dirs?.cacheDir);\n      ensureBackendStartupDirectory(dirs?.workDir);\n      ensureBackendStartupDirectory(dirs?.logDir);\n    } catch (error) {\n      this._status = 'error';\n      throw makeStartupError('spawn', 'aioncore startup directory preparation failed', error);\n    }\n\n    try {\n      this.childProcess = spawn(binaryPath, args, {\n        stdio: ['pipe', 'pipe', 'pipe'],\n        env: buildSpawnEnv(dirs),\n        cwd: dirs?.workDir ?? dbPath,\n        detached: process.platform !== 'win32',\n      });\n    } catch (error) {\n      this._status = 'error';\n      throw makeStartupError('spawn', 'aioncore process spawn threw before startup', error);\n    }\n\n    this.childProcess.stdin?.end();\n\n    backendPid = this.childProcess.pid;\n    const pid = backendPid;","sourceCodeStart":668,"sourceCodeEnd":704,"githubUrl":"https://github.com/iOfficeAI/AionUi/blob/711aa0550ee183ea495dc33e2c05c7943b70a60a/packages/web-host/src/backend-launcher.ts#L668-L704","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Inspect the wrapped `error.cause` — it contains the exact fs error and offending path.","Verify each configured dir (cacheDir, workDir, logDir) is writable by the process user: mkdir -p && touch test.","Fix mounts/permissions (chmod/chown, correct Docker volume) or point the dirs at a writable location via config.","Remove a stale regular file occupying a required directory path.","Ensure HOME/env is set so default dir resolution doesn't produce an invalid path."],"exampleFix":"// before\nconst launcher = new BackendLauncher({ cacheDir: '/opt/aionui/cache' }); // EACCES\nawait launcher.start(); // throws 'startup directory preparation failed'\n\n// after\nconst launcher = new BackendLauncher({ cacheDir: path.join(os.homedir(), '.aionui', 'cache') });\nawait fs.mkdir(cacheDir, { recursive: true }); // preflight\nawait launcher.start();","handlingStrategy":"validation","validationCode":"import fs from 'node:fs';\nfor (const dir of [logDir, cacheDir, workDir].filter(Boolean) as string[]) {\n  fs.mkdirSync(dir, { recursive: true }); // throws early with the offending path\n  fs.accessSync(dir, fs.constants.W_OK);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await launcher.start();\n} catch (e) {\n  if (isStartupError(e) && e.code === 'spawn' && /directory preparation/.test(e.message)) {\n    const cause = e.cause; // fs error: EACCES / EROFS / EEXIST with real path\n    throw new Error(`Fix permissions for startup dirs: ${cause?.path ?? cause?.message}`);\n  }\n  throw e;\n}","preventionTips":["Pre-create all aioncore dirs with recursive mkdir and a write probe before calling start().","Run the process under a user that owns the data/cache/log directories.","In containers, mount volumes at the configured dirs and verify writability in an entrypoint check."],"tags":["spawn","filesystem","permissions","startup","directory-setup"],"backgroundTag":"directory-creation-permission-denied","analyzedSha":"711aa0550ee183ea495dc33e2c05c7943b70a60a","analyzedAt":"2026-08-28T07:56:06.558Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}