{"record":{"id":"b6a3ff9fbe98f1d6","repo":"affaan-m/ECC","slug":"the-local-it-cli-terminated-by-signal-result-si","errorCode":null,"errorMessage":"The local Itô CLI terminated by signal ${result.signal}.","messagePattern":"The local Itô CLI terminated by signal (.+?)\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/ito.js","lineNumber":292,"sourceCode":"    encoding: \"utf8\",\n    // Keep policy helpers immutable for callers, but give child-process\n    // instrumentation its own mutable copy (for example NODE_V8_COVERAGE).\n    env: { ...createSafeItoInvocationEnvironment(environment, args) },\n    stdio: isDeviceLogin ? \"inherit\" : [\"pipe\", \"pipe\", \"pipe\"],\n    maxBuffer: MAX_OUTPUT_BYTES,\n    timeout: isNodeQualification ? NODE_QUALIFICATION_TIMEOUT_MS : undefined,\n    shell: false,\n    windowsHide: true,\n  });\n\n  if (result.stdout) process.stdout.write(result.stdout);\n  if (result.stderr) process.stderr.write(result.stderr);\n  if (result.error) {\n    throw new Error(`The local Itô CLI could not be started: ${result.error.message}`);\n  }\n  if (typeof result.status === \"number\") return result.status;\n  if (result.signal) {\n    throw new Error(`The local Itô CLI terminated by signal ${result.signal}.`);\n  }\n  return 1;\n}\n\nfunction main(argv = process.argv.slice(2), environment = process.env) {\n  try {\n    const parsed = parseArgs(argv, environment);\n    if (parsed.help) {\n      showHelp();\n      return 0;\n    }\n    const executable = resolveItoExecutable(environment);\n    return invokeIto(executable, parsed.invocationArgs, environment);\n  } catch (error) {\n    console.error(`Error: ${error.message}`);\n    return 1;\n  }\n}","sourceCodeStart":274,"sourceCodeEnd":310,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/scripts/ito.js#L274-L310","documentation":"Thrown by invokeIto at scripts/ito.js:291-293 when spawnSync returns no numeric status but a truthy signal — meaning the Itô child was terminated by a signal rather than exiting normally. For the evals subcommand, spawnSync is called with timeout=NODE_QUALIFICATION_TIMEOUT_MS (31 minutes, ito.js:24, 280); when the timeout elapses spawnSync sends the default killSignal (SIGTERM, since killSignal is not overridden) and surfaces it here as result.signal. The thrown message names the signal.","triggerScenarios":"Most commonly: `ecc ito evals ...` exceeding the 31-minute node-qualification timeout and being SIGTERM'd by spawnSync. Also fires on external signals: OOM killer sending SIGKILL (result.signal === 'SIGKILL'), operator/SIGINT during device login, or container runtime SIGTERM. Less common for non-evals commands because timeout is undefined for them, but external signals can still apply.","commonSituations":"Node qualification hanging against unreachable sixtytwo nodes; slow SSH agent forwarding; the canonical CLI waiting on a network call that never returns; container killed by orchestrator during a long evals run; manual Ctrl-C propagated to the child.","solutions":["For SIGTERM on evals: investigate node reachability and SSH agent forwarding; rerun with reachable nodes and a healthy sixtytwo-cli (pinned 0.3.33 per the help text).","For SIGKILL: check dmesg / journalctl for OOM kills and increase memory limits.","For SIGINT: the operator interrupted — rerun when ready.","If 31 minutes is genuinely too short for your node count, split the --nodes list into smaller batches and rerun."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"function preflightNodes(nodeList) {\n  const nodes = nodeList.split(',').map(s => s.trim()).filter(Boolean);\n  if (nodes.length === 0) throw new Error('--nodes empty');\n  return nodes;\n}\n// also surface a clearer warning when the timeout (31m) is likely too short for the node count","typeGuard":null,"tryCatchPattern":"try {\n  return invokeIto(executable, args, env);\n} catch (err) {\n  if (err.message.startsWith('The local Itô CLI terminated by signal')) {\n    const sig = err.message.match(/signal (\\w+)/)[1];\n    if (sig === 'SIGTERM') { /* likely the 31m evals timeout; rerun with smaller node batches */ }\n    else if (sig === 'SIGKILL') { /* OOM or external kill */ }\n  }\n  throw err;\n}","preventionTips":["Batch large --nodes lists so each batch completes well under 31 minutes.","Monitor memory on the host running evals to catch OOM before SIGKILL.","Confirm sixtytwo-cli is pinned to 0.3.33 (per the help text) so qualification does not hang."],"tags":["cli","ito","spawn","signal","timeout","evals"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}