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
nullbecause 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-sourceandtask.finish.open-childrenare still sent, as code and fixed text. The threetask.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 aregisterfield, 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.