{"record":{"id":"68d9353ef79c8560","repo":"can1357/oh-my-pi","slug":"scope-is-not-addressable-from-this-machine","errorCode":null,"errorMessage":"Scope is not addressable from this machine","messagePattern":"Scope is not addressable from this machine","errorType":"console","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/cli/ps-tui.ts","lineNumber":152,"sourceCode":"\t\t});\n\t}\n\n\t#setStatus(text: string): void {\n\t\tthis.#status = text;\n\t\tthis.#statusAt = Date.now();\n\t\tthis.#ui.requestRender();\n\t}\n\n\t// -- actions ---------------------------------------------------------------\n\n\tasync #act(verb: \"stop\" | \"kill\" | \"restart\"): Promise<void> {\n\t\tconst entry = this.#flat[this.#selected];\n\t\tif (!entry) return;\n\t\tconst name = entry.row.snapshot.name;\n\t\tthis.#setStatus(chalk.yellow(`${verb} ${name}…`));\n\t\ttry {\n\t\t\tconst client = await this.#client(entry.scope);\n\t\t\tif (!client) throw new Error(\"Scope is not addressable from this machine\");\n\t\t\tconst result = await client.request(\n\t\t\t\tverb === \"restart\"\n\t\t\t\t\t? { op: \"restart\", name }\n\t\t\t\t\t: { op: \"stop\", name, timeoutMs: verb === \"kill\" ? KILL_GRACE_MS : 5_000 },\n\t\t\t);\n\t\t\tif (result.op !== \"restart\" && result.op !== \"stop\") throw new Error(`Unexpected response ${result.op}`);\n\t\t\tthis.#setStatus(\n\t\t\t\tchalk.green(\n\t\t\t\t\t`${verb === \"restart\" ? \"Restarted\" : verb === \"kill\" ? \"Killed\" : \"Stopped\"} ${daemonLabel(result.daemon)}`,\n\t\t\t\t),\n\t\t\t);\n\t\t\tvoid this.#refresh();\n\t\t} catch (error) {\n\t\t\tthis.#setStatus(\n\t\t\t\tchalk.red(`${verb} ${name} failed: ${error instanceof Error ? error.message : String(error)}`),\n\t\t\t);\n\t\t}\n\t}","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/cli/ps-tui.ts#L134-L170","documentation":"The interactive `omp ps` monitor resolves a broker client per scope via `scopeClient`, which returns `undefined` when the scope cannot be addressed — on Windows the pipe name is derived from the project directory, and for discovered scopes that directory may be unknown (`scope.projectDir === undefined` on win32). The TUI raises this error when you invoke stop/kill/restart on a row whose scope has no usable connection path from this machine.","triggerScenarios":"Pressing s/x/r on a daemon row whose scope has `projectDir === undefined` while `process.platform === \"win32\"`, so `scopeClient` (ps-data.ts:167) short-circuits to `undefined` and `#act` throws before any request is sent.","commonSituations":"On Windows, browsing with `--all` and selecting a daemon from another project's scope whose project dir could not be recovered (unreadable presence file, scope discovered only from a runtime directory); then attempting an action on it.","solutions":["Run `omp ps` from within that project's directory (or pass `--dir <project>`) so the scope's projectDir is known and the pipe name can be derived.","Ping first: the list path back-fills `projectDir` via `{op:\"ping\"}`; refresh the table (press `a` to toggle scopes, wait for refresh) and retry.","On Windows, act on the daemon from a session in the owning project rather than the global monitor."],"exampleFix":"// before\nconst client = await this.#client(entry.scope);\nif (!client) throw new Error(\"Scope is not addressable from this machine\");\n// after\nif (!entry.scope.projectDir && process.platform === \"win32\") {\n  this.#setStatus(chalk.red(`Select this scope via --dir ${entry.scope.runtimeDir}; pipe name needs the project dir`));\n  return;\n}\nconst client = await this.#client(entry.scope);\nif (!client) throw new Error(\"Scope is not addressable from this machine\");","handlingStrategy":"validation","validationCode":"const addressable = (scope: PsScope): boolean =>\n  scope.projectDir !== undefined || process.platform !== \"win32\";\nif (!addressable(entry.scope)) {\n  setStatus(`Scope needs a project dir (Windows); run from the owning project or use --dir`);\n  return;\n}","typeGuard":"function isAddressableScope(scope: PsScope): boolean {\n  return (scope.projectDir ?? (process.platform === \"win32\" ? undefined : scope.runtimeDir)) !== undefined;\n}","tryCatchPattern":"try {\n  const client = await this.#client(entry.scope);\n  if (!client) throw new Error(\"Scope is not addressable from this machine\");\n  /* ... action ... */\n} catch (error) {\n  this.#setStatus(chalk.red(`${verb} ${name} failed: ${error instanceof Error ? error.message : String(error)}`));\n}","preventionTips":["Disable or annotate actions on rows whose scope fails isAddressableScope instead of letting the throw surface.","Run action commands from inside the owning project (or pass --dir) on Windows.","Keep presence files readable so projectDir can be recovered during discovery."],"tags":["windows","named-pipe","scope-resolution"],"backgroundTag":"scope-not-addressable","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}