Skip to main content
An agent can create other agents. A parent mints a child per unit of work, talks to it as an ordinary typed stub, asks the platform which children it has, and ends one when the work it represented is over. The parent keeps no registry of its own. The parent→child relationship is recorded by the platform when the child is created, so children() answers correctly even for a parent that crashed immediately after spawning and came back remembering nothing.
Available from SDK 0.15.0. spawn, children, and despawn are new inherited members, so a subclass that already declares a member by one of those names must rename it or align its signature to override.

spawn()

protected spawn<T>(namespace, name?): Promise<ActorStub & PublicMethods<T>>
Create a child instance of an actor binding and return its stub — one worker per job, minted from inside the agent that needs it. The child is a deliberately created instance owned by this agent, not one materialized by addressing a name. It is the same stub binding.idFromName(...) hands back, typed against the bound class, so calling it is ordinary actor RPC:
Omit name and the child gets a fresh, collision-free one; keep the returned stub’s id if you need to reach that child again later. name is a routing name in your own vocabulary — an order id, an E.164 number, an email — and is encoded into an addressable actor id for you, by the same encoder the front door uses, so a name and its child agree on one instance no matter which side minted it. A name with no faithful id (empty, or one that encodes too long to address) is refused here, before anything is created, with a TypeError naming the name and the limit: a child under an unaddressable id would take writes and then fail to come back the first time it is evicted. Room is finite. When this agent is already at its cap the platform refuses, and the refusal arrives as a QuotaExceededError you can catch at this call site — nothing is created when it throws:
Added with SDK 0.15 — a new inherited member, so a subclass that already declares spawn must rename it (or align its signature to override this method). Type Parameters Parameters Returns Promise<ActorStub & PublicMethods<T>> The child’s stub, typed against the bound actor class. Throws TypeError when name has no addressable actor id, or when the binding cannot create instances. Throws QuotaExceededError when creating the child would exceed a limit already reached.

children()

protected children(): Promise<ChildRef[]>
The children this agent has, as the platform records them. The list is read from the platform every time, not from anything this agent wrote down. That is the point: a parent that crashed after creating three workers and came back remembering nothing still enumerates all three, because the record of who belongs to whom never lived in the parent’s state in the first place. There is no registry to keep in sync, and none to lose. Children can be of different types, so what comes back are descriptors rather than stubs — one class cannot type them all. Each carries the name the child is addressed by, so turning one into a live handle is the ordinary binding call:
An agent with no children gets an empty array, not an error. Added with SDK 0.15 — a new inherited member, so a subclass that already declares children must rename it (or align it to override this method). Returns Promise<ChildRef[]> Every child attached to this agent, of every type.

ChildRef

readonly createdAt: Date
When the child was created.
name
readonly name: string
The child’s address — the same string env.<BINDING>.idFromName(...) takes, so a descriptor becomes a callable stub without translation.
status
readonly status: string
The child’s lifecycle status as the platform reports it.
type
readonly type: string
The actor type the child runs as, e.g. "Worker".

despawn()

protected despawn(child): Promise<void>
End one child of this agent — both halves, in one call. A child that is finished has to be emptied and removed, and doing only one leaves a mess of a specific kind. Emptying alone leaves the name alive: the next call to it activates a blank agent that answers as if it were new. Removing alone leaves everything the child accumulated — its state, its pending timers, its history — sitting in storage under a name nothing can reach again. despawn() does both, in the order that works: the child empties itself first, while it can still be reached, and only then is the name ended. Afterwards a call to the old address is refused rather than answered by a ghost.
Pass the name, or the stub you were handed when the child was created — either identifies the same child. A stub is read for the child it names, not for how to reach it: the child is addressed by the type the platform says it runs as, so a stub minted from the wrong binding still ends the right child rather than emptying one actor and removing another. A name that is not one of this agent’s children is not an error: it is already in the state being asked for, so the call returns having done nothing. That makes a retry after a partial failure safe. Only this agent’s own children can be ended this way. Naming somebody else’s child, or an instance that was never a child at all, does nothing. Added with SDK 0.15 — a new inherited member, so a subclass that already declares despawn must rename it (or align it to override this method). Parameters Returns Promise<void>
Ending a child is not reversible. The platform records the identity as deleted, and a later attempt to create a child under the same name is refused rather than quietly returning a fresh, empty agent. Choose child names you will not need to reuse — a job id rather than a bare customer reference that may come round again.

QuotaExceededError

Thrown when the platform refuses to create a new actor instance because a limit is already reached — the parent’s cap on how many children it may hold, or an account-wide cap on instances. It is an ordinary application error, raised at the call site that asked for the instance, so it can be caught, logged, and reported like any other:
Match it with instanceof, or with err.name === "QuotaExceededError" where the error crossed a boundary that rebuilt it from its name. Nothing was created when this is thrown: the refusal happens before the instance exists, so there is no half-made child to clean up. Retrying the same call only succeeds once room is freed. Extends
  • Error
Constructors Properties

constructor

new QuotaExceededError(args): QuotaExceededError
Parameters Returns QuotaExceededError Overrides Error.constructor

code

readonly code: string | undefined
The machine-readable code from the refusal, when it carried one.

detail

readonly detail: string | undefined
The human-readable detail from the refusal, when it carried one.

status

readonly status: number
The HTTP status the refusal arrived with.