{"record":{"id":"bc6daa1c9e6aa703","repo":"affaan-m/ECC","slug":"ecc-project-dir-must-be-an-absolute-path-within-w","errorCode":null,"errorMessage":"ECC_PROJECT_DIR must be an absolute path within /workspace.","messagePattern":"ECC_PROJECT_DIR must be an absolute path within /workspace\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"docker/plugin-setup/resolve-project-dir.js","lineNumber":15,"sourceCode":"#!/usr/bin/env node\n\n'use strict';\n\nconst path = require('path');\n\nconst WORKSPACE_ROOT = '/workspace';\n\nfunction resolveProjectDir(candidate) {\n  if (\n    typeof candidate !== 'string'\n    || !path.posix.isAbsolute(candidate)\n    || /[\\0\\r\\n]/.test(candidate)\n  ) {\n    throw new Error('ECC_PROJECT_DIR must be an absolute path within /workspace.');\n  }\n\n  const resolved = path.posix.resolve(candidate);\n  if (resolved === WORKSPACE_ROOT || !resolved.startsWith(`${WORKSPACE_ROOT}/`)) {\n    throw new Error('ECC_PROJECT_DIR must be a child path within /workspace.');\n  }\n  return resolved;\n}\n\nfunction main() {\n  try {\n    process.stdout.write(`${resolveProjectDir(process.argv[2])}\\n`);\n  } catch (error) {\n    process.stderr.write(`Error: ${error.message}\\n`);\n    process.exitCode = 2;\n  }\n}\n","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/affaan-m/ECC/blob/01e15490f04e29cfefe3896951f43db46994d8ee/docker/plugin-setup/resolve-project-dir.js#L1-L33","documentation":"The launch() function in the terminal-opener script probes whether the configured terminal (WezTerm) is installed and responsive before spawning it, by running `<terminal> --version`. If detectTerminalCapability() returns available=false (binary missing, probe threw, probe timed out with ETIMEDOUT, or the version probe exited non-zero), launch() throws a combined 'reason: action' message. The action field always tells you to install WezTerm and ensure it is on PATH.","triggerScenarios":"Calling launch(plan) when (a) plan.ok is false — the plan itself is invalid; (b) the wezterm binary is not on PATH so spawnSync throws or returns ENOENT (reason='not-installed'); (c) `wezterm --version` times out after SYNC_TIMEOUT_MS (reason='probe-failed'); (d) `wezterm --version` exits with a non-zero status (reason='probe-failed').","commonSituations":"WezTerm is not installed on a headless/CI machine; wezterm is installed but not on the PATH inherited by the Node process; a shell misconfiguration means the probe cannot find the binary; WezTerm is installed but crashes on `--version` due to a broken config or missing display.","solutions":["Install WezTerm (e.g. brew install --cask wezterm on macOS, or the official package for your OS) and confirm `wezterm --version` works in the same shell that runs this script.","Ensure the wezterm binary directory is on PATH for the Node process — check process.env.PATH inside the script and fix the launching shell/IDE environment.","Call detectTerminalCapability(plan) yourself before launch() and branch on the returned reason/detail instead of letting launch() throw.","If you injected a custom spawnSync via dependencies, verify your stub returns { status: 0, stdout: '...' } rather than erroring."],"exampleFix":"// before\nlaunch(plan); // throws if wezterm missing\n\n// after\nconst cap = detectTerminalCapability(plan);\nif (!cap.available) {\n  console.error(`Cannot launch: ${cap.reason} (${cap.detail}). ${cap.action}`);\n  process.exit(1);\n}\nconst result = launch(plan);","handlingStrategy":"validation","validationCode":"// Call detectTerminalCapability yourself before launch() and branch on the result.\nconst cap = detectTerminalCapability(plan);\nif (!cap.available) {\n  console.error(`Terminal unavailable: ${cap.reason} — ${cap.detail}`);\n  console.error(`Action: ${cap.action}`);\n  process.exit(1);\n}\nconst result = launch(plan);","typeGuard":"// Narrow a capability object before relying on it.\nfunction isCapable(c) {\n  return c && c.available === true && typeof c.version === 'string';\n}\nif (!isCapable(cap)) { /* handle */ }","tryCatchPattern":"try {\n  const result = launch(plan);\n} catch (e) {\n  // e.message is `${reason}: ${action}` — surface both to the user.\n  console.error(`Terminal launch failed: ${e.message}`);\n  process.exitCode = 1;\n}","preventionTips":["Ensure wezterm is installed and on PATH in every environment that runs this script (CI, dev, containers).","Assert `wezterm --version` succeeds in your setup script before invoking the opener.","Call detectTerminalCapability() first and degrade gracefully instead of letting launch() throw."],"tags":["terminal","wezterm","spawn","capability","environment"],"backgroundTag":null,"analyzedSha":"01e15490f04e29cfefe3896951f43db46994d8ee","analyzedAt":"2026-08-13T00:31:08.655Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}