{"record":{"id":"79674162022f654a","repo":"iOfficeAI/OfficeCLI","slug":"127","errorCode":"127","errorMessage":"officecli CLI not found: {bin} is not on PATH nor in the default install location (~/.local/bin, or %LOCALAPPDATA%\\OfficeCLI on Windows). This SDK only forwards commands to the officecli binary, which must be installed separately. Install it:\n    node -e \"require('@officecli/sdk').install()\"   # runs the official installer\n    # or: curl -fsSL https://d.officecli.ai/install.sh | bash\n    # (npm i @officecli/sdk already pulls @officecli/officecli, which bundles the binary)\nAlready installed elsewhere? pass { binary: \"/path/to/officecli\" }.","messagePattern":"officecli CLI not found: \\{bin\\} is not on PATH nor in the default install location \\(~/\\.local/bin, or %LOCALAPPDATA%\\\\OfficeCLI on Windows\\)\\. This SDK only forwards commands to the officecli binary, which must be installed separately\\. Install it:\n    node -e \"require\\('@officecli/sdk'\\)\\.install\\(\\)\"   # runs the official installer\n    # or: curl -fsSL https://d\\.officecli\\.ai/install\\.sh \\| bash\n    # \\(npm i @officecli/sdk already pulls @officecli/officecli, which bundles the binary\\)\nAlready installed elsewhere\\? pass \\{ binary: \"/path/to/officecli\" \\}\\.","errorType":"error_code","errorClass":"OfficeCliError","httpStatus":null,"severity":"error","filePath":"sdk/node/index.js","lineNumber":428,"sourceCode":"  if (IS_WIN && /\\.(cmd|bat)$/i.test(binary)) {\n    // Node refuses to spawn a .cmd/.bat directly without a shell since\n    // CVE-2024-27980 (raises EINVAL). Run it through cmd.exe ourselves,\n    // quoting each token so paths with spaces survive — shell:true would\n    // join the args unquoted and break on the first space. Mirrors Node's\n    // own shell idiom (cmd /d /s /c \"<line>\" + windowsVerbatimArguments)\n    // but with the per-token quoting shell:true omits.\n    const line = [binary, ...argv].map(quoteForCmd).join(' ');\n    cmd = process.env.ComSpec || 'cmd.exe';\n    args = ['/d', '/s', '/c', `\"${line}\"`];\n    opts.windowsVerbatimArguments = true;\n  }\n  return spawnSync(cmd, args, opts);\n}\n\nfunction runCli(binary, argv) {\n  const r = spawnCli(binary, argv);\n  if (r.error && r.error.code === 'ENOENT') {\n    throw new OfficeCliError(127, MISSING_CLI.replace('{bin}', JSON.stringify(binary)));\n  }\n  if (r.error) throw new OfficeCliError(-1, r.error.message);\n  return r;\n}\n\n// Probe a resolved binary by running `<binary> --version`: true iff it actually\n// runs and exits 0. We accept only a WORKING officecli — a present-but-broken\n// file (wrong arch, stale/again-renamed shim, corrupt download) must not be\n// used, and conversely a working officecli on PATH must not be shadowed by a\n// needless auto-install. Output is discarded.\nfunction probeVersion(binPath) {\n  const r = spawnCli(binPath, ['--version'], { stdio: ['ignore', 'ignore', 'ignore'] });\n  return !r.error && r.status === 0;\n}\n\n// ---------------------------------------------------------------- the shell\nclass Document {\n  constructor(filePath, binary = 'officecli', timeoutMs = 30000) {","sourceCodeStart":410,"sourceCodeEnd":446,"githubUrl":"https://github.com/iOfficeAI/OfficeCLI/blob/1ced45e900782c5083ed550ddf328ee974e425e7/sdk/node/index.js#L410-L446","documentation":"Thrown by runCli() (code 127) when spawnSync fails with ENOENT — the officecli binary is neither on PATH nor in the default install locations. The SDK is only a thin pipe-forwarding shell; it never bundles a binary itself, so the CLI must be installed separately. The message gives the exact installer commands and the {binary} override.","triggerScenarios":"Calling open()/create() (or any path that spawns the CLI) before officecli is installed; PATH does not include ~/.local/bin (Unix) or %LOCALAPPDATA%\\OfficeCLI (Windows); autoInstall was disabled and no binary was pre-staged.","commonSituations":"Fresh machine/CI image without the binary; a stripped-down container where the install location isn't on PATH; the binary uninstalled but node_modules left behind; running as a user whose PATH differs from the install-time user.","solutions":["Run the official installer: `node -e \"require('@officecli/sdk').install()\"` (PowerShell on Windows, install.sh via bash elsewhere).","Install the bundling npm package: `npm i @officecli/officecli` (its postinstall fetches the binary) or `curl -fsSL https://d.officecli.ai/install.sh | bash`.","Pass the explicit location: open(file, { binary: '/abs/path/to/officecli' }).","Ensure the install directory is on PATH for the user running Node."],"exampleFix":"// before: oc.open('f.xlsx') -> [exit 127] officecli CLI not found...\n// after: install, or point at an explicit binary\nawait new Promise(r => require('@officecli/sdk').install()); // or: npm i @officecli/officecli\nconst doc = await oc.open('f.xlsx', { binary: '/usr/local/bin/officecli' });","handlingStrategy":"validation","validationCode":"// Ensure the binary exists & is runnable before any open()/create()\nconst { spawnSync } = require('child_process');\nconst fs = require('fs');\nfunction ensureCli(path) {\n  if (!fs.existsSync(path) || spawnSync(path, ['--version'], {stdio:['ignore','ignore','ignore']}).status !== 0) {\n    require('@officecli/sdk').install(); // runs the official installer\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run require('@officecli/sdk').install() (or npm i @officecli/officecli) as a setup step.","Pass {binary: '/abs/path/to/officecli'} to remove PATH dependence in CI.","Confirm the install dir (~/.local/bin / %LOCALAPPDATA%\\OfficeCLI) is on PATH."],"tags":["install","binary-not-found","path","bootstrap"],"backgroundTag":null,"analyzedSha":"1ced45e900782c5083ed550ddf328ee974e425e7","analyzedAt":"2026-08-13T13:01:07.193Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}