CodeHerderSearch⌘KRequest access →

The Placement report

Read the Placement report to see which devices could run a task or agent right now, and exactly why the others can't.

When nothing seems to be picking up a task, the fastest way to find out why is to ask CodeHerder directly. The Placement report answers one question — which of your devices could take this work right now, and why not the others — using the same check the engine itself runs when it staffs a task. Nothing here is a guess: every eligible/ineligible verdict, and every reason given for it, is the actual decision the engine would make.

Placement answers this for one task or agent at a time. To see the same coverage question answered for every stage across your whole workspace at once, see Staffing coverage.

Where to find it

  • On a task’s detail page, the Placement panel.

  • On an agent’s detail page, the Placement panel.

  • From the CLI, for a task:

    ch task placement <taskId>
  • From the CLI, for an agent:

    ch agent placement <agentId>

    Leave off <agentId> to report on your own agent.

Reading the header

The CLI prints a header line before the device table:

fleet: candidates_available · requires: gpu(agent), bin:codex(harness)

fleet: is one of three states:

State What it means
no_devices_linked No device is linked to this workspace at all. This never fixes itself — link a device (see Managing your devices).
candidates_available At least one linked device is eligible right now.
none_eligible Devices are linked, but none currently passes every check. This often clears on its own — a device reconnecting, a cooldown expiring, or a slot freeing up — so it’s worth a second look a few minutes later before you change anything.

requires: lists every capability the work needs and where each one came from:

Source What it means
agent Comes from the target agent’s own required capabilities.
harness Comes from the coding-agent CLI the agent’s launch config uses.
git-host The task’s stage needs to read or write the repo’s git host, so a device must be authenticated to that host.
task-device A hard device requirement set directly on the task or its schedule.

The device table

Below the header, a table lists every device the report considered, with four columns:

Column What it shows
DEVICE The device’s name.
ELIGIBLE Whether this device could take the work right now.
REASON If not eligible, the single decisive reason — see the table below. Prints - when eligible.
DETAIL Whatever else is worth knowing: missing capabilities, other failing checks beyond the headline reason, and any caveats (below).

Eligible devices are listed first, then every device is sorted by name. The report caps the list at 500 devices; if your fleet is that large, it prints a truncation notice rather than silently dropping the rest.

The eight reasons, and what to do about each

Reason What it means What to do
device_offline The device has no active connection right now. Start or restart ch device-server on that machine — see Managing your devices.
device_disabled Someone paused the device. Resume it with ch device undrain <deviceId>, or Enable it in the web app — see Managing your devices. A cloud device draining ahead of an AWS reclaim shows this same reason and needs no action — it clears on its own; see If AWS reclaims the instance.
device_not_workspace_linked The device isn’t linked to this workspace or an ancestor group. Link the device to the workspace — see Managing your devices.
device_caps_mismatch The device doesn’t advertise a capability the work requires. Find which of the four requirement sources asked for it (in the header’s requires: list), then either make the device advertise it (install the missing tool, or set it as a device-side token) or relax the requirement at its source. See Capabilities.
device_unhealthy A readiness check on the device is failing. Check the device’s Health snapshot and fix the failing check — see Managing your devices.
device_sub_exhausted The device’s Claude credential has hit a usage window or spend cap. No action needed — it resumes automatically once the meter resets. See AI usage limits.
device_provision_cooldown This task recently failed to provision on this device and is briefly avoiding it — only shows up in a task’s report. Wait for the cooldown to expire, or try a different device.
device_at_capacity The device is running as many sessions as its concurrency limit allows. Wait for a slot to free up, or raise the device’s concurrency limit — see Managing your devices.

An eligible device carries no reason at all. If a device fails more than one check, DETAIL lists the rest after also: — fixing only the headline reason won’t be enough on its own.

Caveats — gates that would otherwise be invisible

A caveat calls out something the header and table can’t otherwise show you. Some apply to the whole report:

  • link_state_unknown — the workspace-link check couldn’t run this pass, so every device was treated as linked. Re-run the report if a device you expect to see missing isn’t.
  • capacity_unknown — the capacity check couldn’t run this pass, so every device reads as full. This is a temporary blip, not a genuinely saturated fleet — check again shortly.
  • git_host_auth_ungated — the work needs to reach a self-hosted git host, and CodeHerder has no way to check that host’s authentication in advance, so this check is skipped by design. The report names the host so you know which one to double check yourself.
  • agent_requirements_not_folded — you asked for a task’s report without naming an agent, so the agent’s own required capabilities aren’t part of the answer. See Narrowing the answer with --agent below.

Others apply to one device, and show up in that row’s DETAIL after caveats::

  • run_cap_saturated — this device has no free running slot right now. It’s deprioritised for new work, not refused outright, so it can still pick up work once a slot opens.
  • health_unknown — no recent readiness data exists for this device, so its health couldn’t be checked this pass. You’ll usually see this on most or all of your devices — it’s a normal caveat, not a sign anything is wrong.
  • secret_not_acknowledged — every check above passed, but the agent would still fail to start on this device: it references a secret the device owner hasn’t acknowledged yet. See Secrets on a device and Variables to acknowledge it.
  • device_metadata_unknown — CodeHerder couldn’t read this device’s name or secret-acknowledgement state this pass, so the row can’t say more than that. This is a transient blip, not a real problem — re-run the report.

Narrowing the answer with --agent

ch task placement on its own answers “which device could take this task,” using only the task’s own requirements — it doesn’t yet know which agent would run it, so any capability that agent itself requires isn’t part of the check (that’s the agent_requirements_not_folded caveat). Naming a candidate agent sharpens the answer to exactly that agent’s chances, folding in its required capabilities, its harness’s requirements, and whether any secret it references is acknowledged on each device:

ch task placement <taskId> --agent <agentRef>

For a task already assigned to a specific agent, or when you’re deciding which of several agents to assign, run it once per candidate to compare.

  • Staffing coverage — the same coverage question, answered for every stage across your whole workspace at once
  • Why isn’t my task moving? — the full diagnostic walkthrough, with the Placement report as the first stop for a staffing problem
  • Managing your devices — online status, health checks, concurrency, and pausing a device
  • Capabilities — what a capability label is and where each kind is set
  • AI usage limits — how a usage window or spend cap pauses a device and recovers on its own
  • Secrets on a device — acknowledging a device-side secret an agent’s launch config references
  • Variables — scopes, secret variables, and acknowledgement
  • Agents and the CLI — creating and configuring agents
CodeHerder

Round up your herd.

Bring every human and every agent onto one table. Watch the work move. Costs update as it happens.

Try "pricing", "connect a device", or "who reviews the code"

↑↓ move · ↵ open · esc close