An unconfigured Repo Coder sends the owner to a control that does not exist, then declines work it could do
FIS coder (5d14a2e1-140c-466d-beec-ddd331a1e72b, agent coder-repo), 2026-08-11 01:34 — the
instance's entire history, three messages:
owner — "What are the EAP open issues for this repository, for this project?"
❌ repo_remote — "No repository is configured for this agent. Set "Repository path" in the console (Settings → Agent settings) to the chec…"
agent — "No repository is configured for this agent yet. Until a local checkout path is set under Settings → Agent settings, I can't read the file tree, run git commands, or look up issues tied to a specific repo. … Once that's set, I'll be able to: Identify the GitHub remote (owner/repo); Query open issues filtered by an "EAP" label; Cross-reference them against the actual code."
Two defects in four lines, and the agent has not been used since.
1. The control it names is not the control that exists — verified
The sentence is hardcoded at workers/api/src/lib/connectors/repo-local.ts:81:
error: `No repository is configured for this agent. Set "Repository path" in the console
(Settings → Agent settings) to the checkout on your machine, e.g. ~/work/my-repo.`,
"Repository path" is local-repo-chat's field label
(migrations/0066_seed_local_repo_chat_agent.sql, {"id":"repo_path","label":"Repository path",…}).
A coder-repo instance has a different field, labelled "Repository"
(migrations/0063_seed_coder2_agents.sql, {"id":"repo","label":"Repository","type":"text", "description":"The repo this agent owns — a local path (~/dev/my-repo) or owner/name."}).
The connector reads both keys on purpose — REPO_PATH_SETTINGS = ["repo_path", "repo"]
(repo-local.ts:35), with a comment saying the two agents "name the same thing differently and
neither should be renamed". The message did not get the same treatment: it states one label for
both. So the owner is told to look for a setting that is not on his screen. The message is also the
only guidance he gets, because a coder-repo with no repo has nothing else to show him.
2. It declines the GitHub half, which needs no repo setting
github_list_issues takes repo as a tool argument — {repo: "owner/name", state, labels}
(workers/api/src/lib/connectors/github.ts:170-180) — and is allowed: true on this instance. The
local checkout is only how the agent discovers the coordinate (repo_remote); it is not required
to use it. Asked for "the EAP open issues", the honest answer was "I don't know which repo I own —
tell me the owner/name and I'll list them now", which is what #493 is about in its own words. What
it said instead was that it can't look up issues, which is not true, and it then described the
label-filtered query it would run once the path is set — describing a capability it has right now
as blocked on something unrelated.
What to do — cheapest first
1. Make the refusal name the field this agent actually has. resolveTarget already knows which
of repo_path / repo it looked for; carry the settings label with it (read from the agent's own
settingsSchema, which is where the truth is) and interpolate. Fallback to "the repository setting"
rather than a hardcoded guess — a message that names no control beats one that names the wrong one.
2. Say what still works in the same breath. The refusal should end with the GitHub escape hatch,
because that is the whole of what this agent can do unconfigured: "You can still ask me about
GitHub issues, pull requests and CI if you tell me the repository as owner/name." One sentence,
in the same string, so the model cannot separate the "no" from the "but".
3. Consider deriving the coordinate from the setting when it is already owner/name. The
coder-repo repo field explicitly accepts "a local path (~/dev/my-repo) or owner/name", and
repoPathForInstance deliberately skips the owner/name case as "not a checkout, which is honest"
(repo-local.ts:57-60). Honest for the local tools; but in that state the GitHub tools have the
coordinate the owner already typed and still make the model ask for it. Feeding it into the GitHub
tools' repo default is a separate, small change — flagged, not bundled.
Alternatives considered and rejected
- Rename one of the two settings so the message is true. Rejected by the connector's own comment
(repo-local.ts:26-33): they are two different agents' vocabularies and renaming either is a data
migration on live instances.
- Drop the label from the message entirely. Acceptable as a fallback, weaker as the fix — "set
the repository setting" is less useful than the right label when the right label is available.
- Fix it in the prompt instead. Rejected: the wrong string is in the tool result, which is the
most authoritative thing the model reads on that turn. A prompt telling it to distrust its own
tool results is the wrong shape of fix.
Acceptance criteria
Regression risk
- A settings read on a refusal path. The refusal currently costs nothing; reading the schema adds
a query to a path that fires when something is already wrong. Cache it with the capabilities read
that turn, or accept it — it is bounded by how often an agent is misconfigured.
- Point 2 makes the model over-eager to ask for a repo name. Bounded: it should ask once and only
when it has no coordinate, not on every turn. Worth an assertion.
An unconfigured Repo Coder sends the owner to a control that does not exist, then declines work it could do
FIS coder (
5d14a2e1-140c-466d-beec-ddd331a1e72b, agentcoder-repo), 2026-08-11 01:34 — theinstance's entire history, three messages:
Two defects in four lines, and the agent has not been used since.
1. The control it names is not the control that exists — verified
The sentence is hardcoded at
workers/api/src/lib/connectors/repo-local.ts:81:"Repository path"islocal-repo-chat's field label(
migrations/0066_seed_local_repo_chat_agent.sql,{"id":"repo_path","label":"Repository path",…}).A
coder-repoinstance has a different field, labelled"Repository"(
migrations/0063_seed_coder2_agents.sql,{"id":"repo","label":"Repository","type":"text", "description":"The repo this agent owns — a local path (~/dev/my-repo) or owner/name."}).The connector reads both keys on purpose —
REPO_PATH_SETTINGS = ["repo_path", "repo"](
repo-local.ts:35), with a comment saying the two agents "name the same thing differently andneither should be renamed". The message did not get the same treatment: it states one label for
both. So the owner is told to look for a setting that is not on his screen. The message is also the
only guidance he gets, because a
coder-repowith no repo has nothing else to show him.2. It declines the GitHub half, which needs no repo setting
github_list_issuestakesrepoas a tool argument —{repo: "owner/name", state, labels}(
workers/api/src/lib/connectors/github.ts:170-180) — and isallowed: trueon this instance. Thelocal checkout is only how the agent discovers the coordinate (
repo_remote); it is not requiredto use it. Asked for "the EAP open issues", the honest answer was "I don't know which repo I own —
tell me the
owner/nameand I'll list them now", which is what #493 is about in its own words. Whatit said instead was that it can't look up issues, which is not true, and it then described the
label-filtered query it would run once the path is set — describing a capability it has right now
as blocked on something unrelated.
What to do — cheapest first
1. Make the refusal name the field this agent actually has.
resolveTargetalready knows whichof
repo_path/repoit looked for; carry the settings label with it (read from the agent's ownsettingsSchema, which is where the truth is) and interpolate. Fallback to "the repository setting"rather than a hardcoded guess — a message that names no control beats one that names the wrong one.
2. Say what still works in the same breath. The refusal should end with the GitHub escape hatch,
because that is the whole of what this agent can do unconfigured: "You can still ask me about
GitHub issues, pull requests and CI if you tell me the repository as
owner/name." One sentence,in the same string, so the model cannot separate the "no" from the "but".
3. Consider deriving the coordinate from the setting when it is already
owner/name. Thecoder-reporepofield explicitly accepts "a local path (~/dev/my-repo) or owner/name", andrepoPathForInstancedeliberately skips theowner/namecase as "not a checkout, which is honest"(
repo-local.ts:57-60). Honest for the local tools; but in that state the GitHub tools have thecoordinate the owner already typed and still make the model ask for it. Feeding it into the GitHub
tools'
repodefault is a separate, small change — flagged, not bundled.Alternatives considered and rejected
(
repo-local.ts:26-33): they are two different agents' vocabularies and renaming either is a datamigration on live instances.
the repository setting" is less useful than the right label when the right label is available.
most authoritative thing the model reads on that turn. A prompt telling it to distrust its own
tool results is the wrong shape of fix.
Acceptance criteria
coder-repowith no repo set,repo_tree/repo_read_file/repo_git/repo_remoteall refuse with a message naming "Repository"; on a
local-repo-chat, "Repository path".settingsSchema, so a third agent adopting the connector getsits own label with no code change.
owner/nameand then answers — it does notsay it cannot look up issues.
Regression risk
a query to a path that fires when something is already wrong. Cache it with the capabilities read
that turn, or accept it — it is bounded by how often an agent is misconfigured.
when it has no coordinate, not on every turn. Worth an assertion.