{"record":{"id":"92687b081eeaebdf","repo":"affaan-m/ECC","slug":"refusing-to-invoke-an-it-cli-shim-set-ecc-ito-cli-executable","errorCode":null,"errorMessage":"Refusing to invoke an Itô CLI shim. Set ECC_ITO_CLI_EXECUTABLE to the absolute dist/bin/ito.js path.","messagePattern":"Refusing to invoke an Itô CLI shim\\. Set ECC_ITO_CLI_EXECUTABLE to the absolute dist/bin/ito\\.js path\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/ito.js","lineNumber":257,"sourceCode":"      ? segment.toLowerCase() === expected.toLowerCase()\n      : segment === expected;\n  });\n}\n\nfunction isUsableExecutable(candidate) {\n  try {\n    const info = fs.statSync(candidate);\n    if (!info.isFile()) return false;\n    fs.accessSync(candidate, fs.constants.R_OK);\n    return true;\n  } catch {\n    return false;\n  }\n}\n\nfunction buildInvocation(executable, args) {\n  if (!isCanonicalItoEntry(executable)) {\n    throw new Error(\n      `Refusing to invoke an Itô CLI shim. Set ${EXECUTABLE_OVERRIDE} to the absolute dist/bin/ito.js path.`\n    );\n  }\n  return Object.freeze({\n    executable: process.execPath,\n    args: Object.freeze([executable, ...args]),\n  });\n}\n\nfunction invokeIto(executable, args, environment = process.env) {\n  const invocation = buildInvocation(executable, args);\n  const command = getInvocationCommand(args);\n  const isNodeQualification = command === \"evals\";\n  const isDeviceLogin = command === \"login\";\n  const result = spawnSync(invocation.executable, invocation.args, {\n    cwd: process.cwd(),\n    encoding: \"utf8\",\n    // Keep policy helpers immutable for callers, but give child-process","sourceCodeStart":239,"sourceCodeEnd":275,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/ito.js#L239-L275","documentation":"buildInvocation is the last line of defense before the bridge spawns the Itô CLI: it re-validates that the resolved executable is the canonical dist/bin/ito.js and refuses anything else. This guards against shims or wrappers intercepting a credential-bearing client, since ECC deliberately never discovers the CLI through PATH.","triggerScenarios":"Any ecc ito command where the executable handed to buildInvocation (via resolveItoExecutable/invocation) is not the canonical entry — e.g. the override was changed between validation and invocation, or a modified caller passes a shim path directly.","commonSituations":"Users wrapping the CLI in shell wrappers for logging or env injection; patched forks that relax earlier checks; CI images that substitute a downloaded binary.","solutions":["Set ECC_ITO_CLI_EXECUTABLE to the absolute canonical path .../cli/ito-compute-cli/dist/bin/ito.js and remove any wrapper indirection.","Apply env vars or logging around the invocation (e.g. in the shell that launches ECC) instead of wrapping the CLI binary itself.","Rebuild from the canonical repo if you need customization; do not point ECC at a renamed/copied entry.","Confirm no script or profile rewrites ECC_ITO_CLI_EXECUTABLE after your export (check shell rc files and CI env)."],"exampleFix":"// before\nexport ECC_ITO_CLI_EXECUTABLE=/usr/local/bin/ito-wrapper   # shim\n// after\nunset ITO_WRAPPER;\nexport ECC_ITO_CLI_EXECUTABLE=/opt/ito-cloud-runtime/cli/ito-compute-cli/dist/bin/ito.js","handlingStrategy":"validation","validationCode":"const override = process.env.ECC_ITO_CLI_EXECUTABLE;\nif (override && !override.endsWith('/cli/ito-compute-cli/dist/bin/ito.js')) {\n  throw new Error('Override must be the absolute dist/bin/ito.js path, not a shim');\n}","typeGuard":"const isCanonicalEntry = (p) => typeof p === 'string' && /\\/cli\\/ito-compute-cli\\/dist\\/bin\\/ito\\.js$/.test(p);","tryCatchPattern":"try { await eccIto(['status']); } catch (e) { if (e.message.includes('Refusing to invoke an Itô CLI shim')) { console.error('Remove the wrapper and set ECC_ITO_CLI_EXECUTABLE to dist/bin/ito.js'); } else throw e; }","preventionTips":["Do not wrap the CLI in shell scripts; apply env/logging in the launching shell instead","Grep shell rc files and CI configs for rewrites of ECC_ITO_CLI_EXECUTABLE","Treat the canonical-entry requirement as a security invariant, not an inconvenience"],"tags":["security","cli","config"],"backgroundTag":"invalid-config-value","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}