[API reference](https://evolu.dev/docs/api-reference) › [@evolu/common](https://evolu.dev/docs/api-reference/common) › [Task](https://evolu.dev/docs/api-reference/common/Task) › daemon

```ts
function daemon<T, E, D>(task: Task<T, E, D>): Task<T, AbortError | E, D>;
```

Defined in: [packages/common/src/Task.ts:4809](https://github.com/evoluhq/evolu/blob/a18269a1b822c670b507c6a9b73b23eed32551fe/packages/common/src/Task.ts#L4809)

Starts a [Task](https://evolu.dev/docs/api-reference/common/Task/type-aliases/Task) with [Run.daemon](https://evolu.dev/docs/api-reference/common/Task/interfaces/Run#daemon) and waits until it settles or the
current Run aborts.

When the current Run aborts, this helper requests abort for the daemon Task
and returns [AbortError](https://evolu.dev/docs/api-reference/common/Task/variables/AbortError) without waiting for that daemon Task to observe
abort, clean up, or settle. This makes the wait abortable, not the underlying
execution. The daemon Task continues under root Run ownership until it
settles, observes abort, or the root Run is disposed.

This is not a replacement for direct [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) support in operations
that can observe abort, such as [fetch](https://evolu.dev/docs/api-reference/common/Http/functions/fetch), timers that accept a signal, or
callback APIs that accept a signal. Use it as an escape hatch for Tasks that
ignore abort when an abort request must stop waiting immediately.

Do not wrap a Task that keeps using a resource the caller may release after
this wrapper returns, unless the Task reliably observes abort before using
that resource. The daemon Task can continue after the caller stops waiting.
Later domain `Err` results from the daemon Task are discarded after the
caller stops waiting. Defects from the daemon Task remain visible to the root
Run: if it later throws or rejects, the root Run still panics and reports the
defect.

Compose with [race](https://evolu.dev/docs/api-reference/common/Task/functions/race) or [timeout](https://evolu.dev/docs/api-reference/common/Task/functions/timeout) when the losing Task must not
delay the winner. Those helpers normally abort losing Tasks and wait for them
to settle, keeping cleanup and late defects inside the caller's lifetime. A
Task that ignores abort can keep them waiting.

`run.abortable(task)` returns an owned child Fiber and requests abort through
that Fiber; `daemon(task)` starts a daemon child and stops waiting when the
current Run aborts. [unabortable](https://evolu.dev/docs/api-reference/common/Task/variables/unabortable) masks abort for a Task that must
finish once started; daemon lets a Task outlive the caller.

Because the Task starts with [Run.daemon](https://evolu.dev/docs/api-reference/common/Task/interfaces/Run#daemon), a recorded abort request
returns AbortError before the Task starts — including a request masked by
[unabortable](https://evolu.dev/docs/api-reference/common/Task/variables/unabortable), even though `run.signal` stays un-aborted inside the
mask. Inside a masked body, wrapping a Task with `daemon` opts the wait back
into abort observation; omit the wrapper when the mask should keep the Task
running.

### Example

```ts

let finished = false;
let finishTask = (): void => {};
const taskNotUsingAbort: Task<string> = () =>
  new Promise((resolve) => {
    finishTask = () => {
      finished = true;
      resolve(ok("done"));
    };
  });

{
  await using run = createRun();
  const result = await run(timeout(daemon(taskNotUsingAbort), "1ms"));
  assert(!result.ok);
  expect(result.error.type).toBe("TimeoutError");
  expect(finished).toBe(false);
  finishTask();
}
expect(finished).toBe(true);
```

Promise-producing operations should start inside the Task, not before it.

```ts

type ResultValue = string;
interface MyError {
  readonly type: "MyError";
}
const createPromiseReturningResult = (): Promise<
  Result<ResultValue, MyError>
> => Promise.resolve(ok("value"));

const task: Task<ResultValue, MyError> = () => createPromiseReturningResult();

await using run = createRun();
expectOk(await run(task), "value");
```

Do not reuse an already-running Promise. It started outside the Task, so the
Run cannot own its lifetime or request abort before it begins.

```ts

type ResultValue = string;
interface MyError {
  readonly type: "MyError";
}
let promiseStarted = false;
const createPromiseReturningResult = (): Promise<
  Result<ResultValue, MyError>
> => {
  promiseStarted = true;
  return Promise.resolve(ok("value"));
};

// Wrong: the Promise starts now, before a Run starts the Task.
const promise = createPromiseReturningResult();
const task: Task<ResultValue, MyError> = () => promise;

expect(promiseStarted).toBe(true);
expectTypeOf(task).toEqualTypeOf<Task<ResultValue, MyError>>();
```