Skip to content

"Run npm i -g @proagentstore/cli on that machine" names no machine — the owner has two runners, already upgraded one, and the agent is pinned to the other #524

Description

@serge-ivo

What the owner saw

Three times in 40 minutes, on the same agent:

2026-08-12 03:23:28repo_find This machine's runner is too old to search this repository — it needs CLI 0.4.49 or newer. Run npm i -g @proagentstore/cli on that machine and restart pags up.
2026-08-12 04:03:31repo_grep (same) — twice.

and the agent relayed it faithfully:

The search tools are unavailable right now — the local runner needs to be updated before I can read the code. The error says to run npm i -g @proagentstore/cli on your machine and restart pags up.

He has two machines connected, and he has already upgraded one of them to 0.4.49. The message cannot tell him which machine it means, and nothing on the surface tells him this agent is pinned to the other one. Following the instruction on the obvious machine — the one he is sitting at — changes nothing.

Measured, live

GET /v1/terminals/nodes, 2026-08-12 04:16 UTC, both connected:

node machineId runner aka
RLs-MacBook-Air 3901c9c4-… 0.4.49 Mac, RLs-MacBook-Air.local
Sergeys-Mac-mini.local 8de74159-… 0.4.45

Instance bd43f4de-ef35-4051-bdec-43f8571414a1 ("Chess coder 2"), config.runnerNode = "Sergeys-Mac-mini.local" — the 0.4.45 machine. On that node the instance reads connected: true, bound: true; the 0.4.49 machine holds live sockets for 15 of the owner's other instances.

REPO_SEARCH_MIN_CLI = "0.4.49" (workers/api/src/lib/connectors/repo-local.ts:53) — so repo_find and repo_grep are exactly the two tools the pinned machine cannot serve. Its other repo tools work: at 04:03:55 the same instance ran repo_read_file and repo_git successfully against the same checkout.

Mechanism — two correct decisions composing into an unactionable message

1. The pin is authoritative and deliberately never falls through. workers/api/src/lib/runner-client.ts:74-100, docstring and code:

"When pinned, that machine is authoritative: we do NOT silently fall back to another node when it's offline — doing so would run the agent somewhere the user didn't choose and misreport 'online' for the wrong machine."

That is right, and #379/#380/#461/#500 are the trail of bugs from getting it wrong. It is not the defect.

2. The remedy names no machine. workers/api/src/lib/connectors/repo-local.ts:57-61:

function runnerTooOld(e: unknown, what: string): string | null {
	const message = e instanceof Error ? e.message : String(e);
	if (!/ 404|not found/i.test(message)) return null;
	return `This machine's runner is too old to ${what} — it needs CLI ${REPO_SEARCH_MIN_CLI} or newer. Run \`npm i -g @proagentstore/cli\` on that machine and restart \`pags up\`.`;
}

The comment above REPO_SEARCH_MIN_CLI gets the principle exactly right — "Named, not 'update the CLI' — a version without a number is one somebody has to go and find" — and then stops one step short: the version is named, the machine is not, and the machine is the part the reader has to go and find. Worse, "that machine" is a phrase the reader will resolve to the machine in front of them, which here is the 0.4.49 one that needs nothing.

This is the #513 / #517 class: a remedy the reader cannot execute. #517 fixed the case where the remedy was discarded; this is the case where it is relayed intact and is still not actionable.

What to do, cheapest first

  1. Name the machine, and its version. runnerTooOld is called from a handler that has already resolved the connection (resolveTargetgetBoundRunnerConn), and RunnerConn carries runnerNode. Thread it in:

    The runner on **Sergeys-Mac-mini.local** is too old to search this repository (it has 0.4.45; this needs 0.4.49 or newer). Run npm i -g @proagentstore/clion **Sergeys-Mac-mini.local** and restartpags up there.
    One parameter, one call site, and it is the whole difference between a message the owner can act on and one he cannot.

  2. Say the pin is why it is that machine. When config.runnerNode is set, append: "This agent is pinned to that machine (Settings → Runs on), so it will not use another one." Without this the owner has no way to discover the pin from the failure — and the pin is the only reason the upgraded machine is not being used.
  3. Say when a capable machine exists. GET /v1/terminals/nodes already computes every node's runnerVersion. When another of the owner's connected nodes satisfies REPO_SEARCH_MIN_CLI, name it: "RLs-MacBook-Air is connected and already runs 0.4.49 — repin this agent there, or upgrade the pinned machine." That turns a dead end into a choice.
  4. Generalise it. SWITCH_BRANCH_MIN_CLI in repo-policy-act.ts is the same pattern and will read the same way. One helper — "which machine, running what, needs what" — serves both.

Alternatives rejected

Acceptance

  • With an instance pinned to a node whose runner_version < REPO_SEARCH_MIN_CLI, repo_find/repo_grep return a message that contains the node name, its actual version, the required version, and — when the pin is set — that the agent is pinned there.
  • When another connected node meets the requirement, the message names it.
  • Unit test on the message builder (pure, as repoMissingMessage already is) covering: pinned + no capable alternative; pinned + capable alternative present; unpinned.

Regression risk

The message is relayed verbatim into chat and is now longer; #517's own finding was that a long remedy gets truncated away before the owner sees it. Whatever cap applies to a tool-result line must keep the machine name — put it in the first clause, not after the version numbers. Test that the truncated form still names the machine.

Related: #508 (added repo_find/repo_grep and REPO_SEARCH_MIN_CLI), #513 and #517 (remedies the reader cannot execute), #379 / #461 (the pinned-machine diagnosis this should reuse).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    backendBackend / Worker / API workbugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions