stablyai/orca · error
--serve-project-root must be a directory: ${options.projectR
Error message
--serve-project-root must be a directory: ${options.projectRoot} What it means
Thrown by printServeReady when --serve-project-root points to something that is not a directory (statSync().isDirectory() is false). Guards against pointing the serve runtime at a file, a broken symlink, or a nonexistent path — none of which can serve as a project root.
Source
Thrown at src/main/index.ts:1888
return null
}
}
}
async function printServeReady(options: ServeOptions): Promise<void> {
if (!runtime || !runtimeRpc) {
throw new Error('Runtime server must be initialized before printing serve readiness')
}
if (options.recipeJson) {
if (!options.projectRoot) {
throw new Error('--serve-recipe-json requires --serve-project-root')
}
if (!isAbsolute(options.projectRoot)) {
throw new Error(`--serve-project-root must be absolute: ${options.projectRoot}`)
}
const projectRootStats = statSync(options.projectRoot)
if (!projectRootStats.isDirectory()) {
throw new Error(`--serve-project-root must be a directory: ${options.projectRoot}`)
}
}
const boundEndpoint = runtimeRpc.getWebSocketEndpoint()
const advertised = boundEndpoint
? resolveAdvertisedPairingEndpoint(boundEndpoint, options.pairingAddress)
: null
const pairing = options.noPairing
? ({
available: false,
reason: 'disabled_by_operator',
guidance: 'Restart without --no-pairing to create a client pairing offer.'
} as const)
: runtimeRpc.createPairingOffer({
address: options.pairingAddress,
name: `${options.mobilePairing ? 'Mobile' : 'CLI'} ${new Date().toLocaleDateString()}`,
scope: options.mobilePairing ? 'mobile' : 'runtime'
})
const pairingQr =View on GitHub (pinned to 1136503c6a)
Solutions
- Verify the path exists and is a directory: `ls -ld <path>`.
- Create the directory first if it doesn't exist: `mkdir -p <path>`.
- Point at the project's root folder, not at a file inside it.
Example fix
// before --serve-project-root /home/me/projects/myapp/package.json // after --serve-project-root /home/me/projects/myapp
Defensive patterns
Strategy: validation
Validate before calling
import { statSync } from 'node:fs'
function ensureProjectRootDir(p: string): void {
const stats = statSync(p) // throws ENOENT if missing
if (!stats.isDirectory()) throw new Error(`Not a directory: ${p}`)
} Type guard
function isExistingDirectory(p: unknown): p is string {
if (typeof p !== 'string') return false
try { return statSync(p).isDirectory() } catch { return false }
} Prevention
- mkdir -p the project root before launching serve mode.
- Point at directories, never at files.
- Validate existence and type in the launcher before forwarding to the CLI.
When it happens
Trigger: Passing a path to a file, a dangling symlink, or a nonexistent path to --serve-project-root. statSync will either find a non-directory or throw ENOENT (which surfaces as the same logical failure).
Common situations: Typo in the path; pointing at a file instead of its parent directory; path resolved before the directory was created; symlink target removed; path copied from a different machine where the layout differs.
Related errors
- --serve-project-root must be absolute: ${options.projectRoot
- invalid_argument
- Invalid --serve-port value: ${rawPort}
- --higher-is-better requires a metric key
- Usage: node config/scripts/compare-benchmark-artifacts.mjs -
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/a8efafeabff08cbb.
Report an issue: GitHub.