stablyai/orca · error · Error
pnpm install completed, but node_modules/.bin/expo is still
Error message
pnpm install completed, but node_modules/.bin/expo is still missing.
What it means
Thrown by the mobile Expo CLI launcher after it auto-runs `pnpm install --frozen-lockfile` in the mobile directory and still cannot locate node_modules/.bin/expo. The script first checks for expo; if missing it installs deps; if expo is STILL missing post-install, it treats the dependency state as broken rather than launching a missing binary.
Source
Thrown at mobile/scripts/mobile-expo-cli.mjs:53
})
}
export async function ensureMobileExpoCli(mobileDir, logger = {}) {
if (getMobileExpoExecutablePath(mobileDir)) {
return
}
const message = 'Mobile dependencies are missing; running pnpm install --frozen-lockfile...'
if (logger.logStep) {
logger.logStep('deps', message)
} else {
console.log(`[start] ${message}`)
}
await runPnpmInstall(mobileDir)
if (!getMobileExpoExecutablePath(mobileDir)) {
throw new Error('pnpm install completed, but node_modules/.bin/expo is still missing.')
}
logger.logSuccess?.('Mobile dependencies installed')
}
View on GitHub (pinned to 1136503c6a)
Solutions
- Verify `expo` is present in mobile/package.json dependencies/devDependencies and run `pnpm install` (without --frozen-lockfile) to regenerate the lockfile if needed.
- Delete mobile/node_modules and mobile/pnpm-lock.yaml's effect by removing node_modules, then reinstall.
- Check getMobileExpoExecutablePath() handles the current OS (look for expo vs expo.cmd vs expo.ps1).
- Confirm pnpm is the intended manager and the workspace root's pnpm-workspace.yaml includes mobile.
Example fix
// before
await runPnpmInstall(mobileDir)
if (!getMobileExpoExecutablePath(mobileDir)) {
throw new Error('pnpm install completed, but node_modules/.bin/expo is still missing.')
}
// after — capture install exit code and report it
const installResult = await runPnpmInstall(mobileDir)
if (!getMobileExpoExecutablePath(mobileDir)) {
throw new Error(`pnpm install (exit ${installResult.code}) completed, but node_modules/.bin/expo is still missing. Check that 'expo' is in package.json.`)
} Defensive patterns
Strategy: validation
Validate before calling
// Verify expo is declared before attempting install
import { readFileSync } from 'node:json'
const pkg = JSON.parse(readFileSync(join(mobileDir, 'package.json'), 'utf8'))
const hasExpo = Boolean((pkg.dependencies?.expo) || (pkg.devDependencies?.['expo-cli']))
if (!hasExpo) {
throw new Error("'expo' is not in mobile/package.json; add it before launching")
} Type guard
function expoExecutableExists(mobileDir: string): boolean {
return Boolean(getMobileExpoExecutablePath(mobileDir))
} Try / catch
try {
await runPnpmInstall(mobileDir)
} catch (installErr) {
throw new Error(`pnpm install failed: ${(installErr as Error).message}`)
}
if (!getMobileExpoExecutablePath(mobileDir)) {
throw new Error('pnpm install completed, but node_modules/.bin/expo is still missing.')
} Prevention
- Keep expo in package.json and the lockfile in sync.
- Make getMobileExpoExecutablePath() cross-platform (expo / expo.cmd / expo.ps1).
- Run `pnpm install` non-frozen locally if the lockfile is stale before pushing.
When it happens
Trigger: mobile/node_modules/.bin/expo is absent after pnpm install — e.g. expo is not declared in package.json, the lockfile is out of sync and --frozen-lockfile exits but the script did not catch it, pnpm hoisted expo elsewhere, or the platform-specific expo binary shim failed to link.
Common situations: A package.json change that removed expo-cli/expo without updating the lockfile, a corrupted node_modules from a previous interrupted install, a pnpm version mismatch that lays out .bin differently, or running on Windows where .bin/expo is expo.cmd and the path check looks for the wrong suffix.
Related errors
- Could not resolve package ${packageName} from ${fromDir}
- Could not find package.json for ${packageName}
- Cannot build the validation app: electron-vite entry not fou
- npm_execpath is required; run this harness through pnpm
- [verify-linux-glibc-floor] objdump not found. Install binuti
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/5e0a958fd08846c7.
Report an issue: GitHub.