Skip to content

Team task warnings

A warning is advice returned with a team task call that succeeded. The task was created, assigned, reassigned or finished; the warning says what teams have learned is usually wrong about that step. It never blocks the call and never replaces an error. For what a team task is, see Team tasks; to act on a warning, see Hand work to your team as tasks.

Warnings are an experiment, introduced by hadron-server#2198 (merged in #2207). They are not yet part of the platform's specified contract, so the codes below may change before they are.

The codes

The list is closed per release: a client must tolerate a code it does not know. The text of each code is fixed. It is never filled in with a name, id or reason.

Code Raised on Fixed text
task.create.no-source create This task has no source: say where the work came from (an issue URL or a node URN).
task.assign.assignee-unavailable assign, reassign, and create with an assignee The assignee is marked unavailable for work, so the task may wait.
task.assign.assignee-busy assign, reassign, and create with an assignee The assignee already has an open task.
task.assign.assignee-paused assign, reassign, and create with an assignee The assignee has paused itself, so the task may wait.
task.finish.open-children finish This task still has open child tasks.

The three task.assign.* codes describe another worker's state. They are raised only when the assignee is a worker other than the caller, never for a person or for assigning to yourself, and they are sent only to a caller who may already see that fact on the team roster; for anyone else they are simply absent, so a missing assignee warning is not proof that the assignee is free.

Where they appear

GraphQL

Warnings are in the response's extensions.warnings, not in errors. The data and errors envelope is unchanged. Each entry is:

Field Meaning
path The mutation's response key: its alias if it has one, otherwise its name. Several mutations in one request stay apart by this key.
code One of the codes above, or a code added later.
text The fixed text for the code.
register Optional. Where the App's register maps this code. Absent for a caller that has no Agent.

The operations are createAgentTask, assignAgentTask, reassignAgentTask and finishAgentTask. A real response from createAgentTask with no source (run against production with hadron api; the id is shortened):

{
  "data": {
    "createAgentTask": { "id": "01a15dbb…", "title": "docs#452 warning example - cancel immediately", "status": "BACKLOG" }
  },
  "extensions": {
    "warnings": [
      {
        "path": "createAgentTask",
        "code": "task.create.no-source",
        "text": "This task has no source: say where the work came from (an issue URL or a node URN)."
      }
    ]
  }
}

That call came from a person's token, so there is no register field.

MCP

The task tools append one line per warning after the task text:

Warning [task.create.no-source]: This task has no source: say where the work came from (an issue URL or a node URN).

When the register maps the code to a role task, the line ends → <task urn>. When the code is unmapped it ends (no task mapped). An unresolved lookup adds nothing. The format is read from the server source, not from a live MCP run.

CLI and portal

Not documented here yet. The CLI and portal changes that render warnings are tracked in hadron-cli#962 and hadron-portal#1214; this page will cover them once they have shipped. Until then, use the GraphQL or MCP surface to see a warning.

The register

The register maps a warning code to the role task that tells a worker what to do about it. Entries are nodes named register:<code> in the App's Team Agent's system memory, each carrying data.registerEntry = { code, taskLoc }. The code is looked up through the Team Agent's chain, then the entry's taskLoc is resolved through the caller's own Agent chain, nearest first.

register has one of three states:

register.state Fields Meaning
mapped taskLoc, taskUrn The register maps the code and the caller's Agent chain resolves the task.
unmapped none The App has no Team Agent to map through, or no register entry for this code that you can read, or the entry names no task.
unresolved none There is a readable entry, but its taskLoc does not resolve to a runnable task you can read through your own Agent chain (or your Agent has no system memory).

A caller with no Agent (a person, or a session the server cannot tie to one Agent) gets no register field at all. The lookup runs after the write has committed and never fails the call.

Known defect. A worker driven by a plain App member has been reported to get unmapped or unresolved even where an entry exists. The suspected cause is a missing App context on its register read; that is not a verified root cause. The server team tracks it as a defect, not as intended behaviour, in a comment on hadron-server#2206, and it is expected to resolve there. This page has not reproduced it. Until it does, do not rely on register being present or resolved for such a worker.

Limits

  • Caps. At most 5 warnings per operation and 20 per response, taken in operation order and then code order. A duplicate code in one operation is dropped.
  • Only after a commit. A warning is recorded after its write committed, so a failed operation never carries one. In a response where the data is null because a sibling mutation failed, a committed write's warning can still be present.
  • Bounded lookups. The privacy check and the register lookup together have a fixed time budget per request, and a lookup that times out or fails stops further enrichment. task.create.no-source and task.finish.open-children are still sent, as code and fixed text. The three task.assign.* codes are omitted unless the roster privacy check was answered "yes", so a timeout never discloses another worker's state; their absence is not a statement about the assignee. A warning whose register lookup did not resolve is sent without a register field, and a register result already found earlier in the same request can still be reused.

Availability

Server main at eb2cb49 (hadron-server#2207), live on srv.hadronmemory.com. The code list, caps and register states above are read from that source; the GraphQL example is a live run.