# What Are the Six States of a Fiber in Cordis?

> Explore the six states of a Fiber in Cordis: PENDING, LOADING, ACTIVE, FAILED, DISPOSED, and UNLOADING. Understand its plugin execution lifecycle.

- Repository: [Cordiverse/cordis](https://github.com/cordiverse/cordis)
- Tags: deep-dive
- Published: 2026-08-24

---

**A Cordis Fiber cycles through six distinct lifecycle states—PENDING, LOADING, ACTIVE, FAILED, DISPOSED, and UNLOADING—defined in the `FiberState` enum to manage plugin execution context.**

In the `cordiverse/cordis` ecosystem, a **Fiber** represents the execution context of a plugin, tracking its lifecycle through precisely defined states. Understanding these **six states of a Fiber in Cordis** is essential for debugging plugin behavior, handling errors, and coordinating asynchronous operations. The state machine is implemented in the core package and exposed through the `Fiber` class's `state` property.

## The FiberState Enum Definition

The `FiberState` enumeration is declared in [`packages/core/src/fiber.ts`](https://github.com/cordiverse/cordis/blob/main/packages/core/src/fiber.ts) at lines 78-85. This enum provides the canonical definition of all possible states a Fiber can occupy during its lifetime. The `Fiber` class maintains its current condition via the `state` property, updating it internally whenever lifecycle transitions occur, such as when an epoch switches from inactive to active or when an error is caught during plugin execution.

## The Six States Explained

Cordis fibers follow a strict state machine with six possible values. Each state represents a specific phase in the plugin lifecycle and determines what operations are valid at that moment.

### PENDING

**PENDING** indicates the fiber has been instantiated but has not yet begun loading its plugin implementation. This is the initial state before any effect code runs.

### LOADING

When a fiber enters the **LOADING** state, it is actively executing the plugin's effect function and initializing its implementation. This state covers the period between instantiation and full activation.

### ACTIVE

The **ACTIVE** state signifies the plugin is fully loaded and its effect is currently running. This is the operational state where the plugin can accept API calls and perform its intended functions. The `assertActive()` method guards critical API calls, throwing a `CordisError` if invoked while the fiber is not in this state.

### FAILED

A fiber transitions to **FAILED** when an error occurs during the loading phase or while executing the plugin effect. This state indicates the fiber is in an error condition and cannot proceed to ACTIVE until the issue is resolved.

### UNLOADING

The **UNLOADING** state occurs when the fiber is shutting down and disposing of all registered disposables. This transitional state ensures cleanup operations complete before the fiber is permanently discarded.

### DISPOSED

Once cleanup finishes, the fiber enters the **DISPOSED** state. At this point, the fiber has been permanently disposed and can no longer be used or restarted. Any attempt to interact with a disposed fiber will result in errors.

## State Transitions and Event Coordination

State transitions in Cordis are not merely internal bookkeeping; they drive the entire plugin coordination system. When a fiber moves between states, it emits `internal/status` events to the surrounding context, enabling reactive programming patterns.

The transition logic ensures plugins load, run, and unload predictably. For example, the `restart()` method programmatically moves a fiber through the sequence of UNLOADING → PENDING → LOADING → ACTIVE, allowing hot-reloading of plugin implementations without destroying the parent context.

## Working with Fiber States in Code

You can inspect and react to fiber states using the Cordis context API. The `ctx.fiber` property provides access to the current fiber instance and its state machine.

To check the current state of a fiber:

```typescript
import { Context } from '@cordis/core'

function printFiberState(ctx: Context) {
  const state = ctx.fiber.state
  console.log('Current fiber state:', state)
}

```

To react to state changes in real-time:

```typescript
ctx.fiber.context.on('internal/status', (fiber, oldState) => {
  console.log(`Fiber transitioned from ${oldState} to ${fiber.state}`)
})

```

To manually trigger a lifecycle restart:

```typescript
await ctx.fiber.restart()
console.log('After restart, state is', ctx.fiber.state)

```

## Key Source Files for State Management

The fiber state implementation spans four critical files in the core package:

- **[`packages/core/src/fiber.ts`](https://github.com/cordiverse/cordis/blob/main/packages/core/src/fiber.ts)**: Defines the `FiberState` enum, the `Fiber` class, and all state-transition logic including the `assertActive()` validation method.
- **[`packages/core/src/context.ts`](https://github.com/cordiverse/cordis/blob/main/packages/core/src/context.ts)**: Extends the `Context` class with a `fiber` property and emits the `internal/status` lifecycle events during state changes.
- **[`packages/core/src/registry.ts`](https://github.com/cordiverse/cordis/blob/main/packages/core/src/registry.ts)**: Manages plugin registration and interacts with fiber states during the addition and removal of plugins from the application.
- **[`packages/core/src/reflect.ts`](https://github.com/cordiverse/cordis/blob/main/packages/core/src/reflect.ts)**: Handles implementation checks that can trigger state transitions, particularly failures that move a fiber into the FAILED state.

## Summary

- Cordis fibers use six distinct states defined in the `FiberState` enum: **PENDING**, **LOADING**, **ACTIVE**, **FAILED**, **UNLOADING**, and **DISPOSED**.
- The `Fiber` class tracks its current condition via the `state` property declared in [`packages/core/src/fiber.ts`](https://github.com/cordiverse/cordis/blob/main/packages/core/src/fiber.ts).
- **ACTIVE** is the only state where full plugin operations are permitted; `assertActive()` enforces this constraint by throwing `CordisError` for invalid states.
- State transitions emit `internal/status` events, enabling reactive patterns and lifecycle coordination across the plugin ecosystem.
- The `restart()` method moves fibers through shutdown and reinitialization sequences for hot-reloading scenarios.

## Frequently Asked Questions

### How do I check if a Cordis fiber is ready to accept operations?

Check the `ctx.fiber.state` property against the `FiberState.ACTIVE` enum value. Alternatively, use `ctx.fiber.assertActive()`, which throws a `CordisError` if the fiber is in any state other than ACTIVE, providing runtime guards for critical operations.

### What happens when a fiber enters the FAILED state?

When a fiber transitions to **FAILED**, it indicates an uncaught error occurred during plugin loading or execution. The fiber remains in this error state until explicitly handled, preventing further automatic transitions. You must typically restart the fiber or dispose of it manually to recover from this condition.

### Can I restart a fiber that is in the DISPOSED state?

No, once a fiber enters the **DISPOSED** state, it has been permanently shut down and cannot be restarted. The `restart()` method only works on fibers that have not reached final disposal. To reload a disposed plugin, you must create a new fiber instance through the registry system in [`packages/core/src/registry.ts`](https://github.com/cordiverse/cordis/blob/main/packages/core/src/registry.ts).

### Which source file contains the FiberState enum definition?

The `FiberState` enum is defined in [`packages/core/src/fiber.ts`](https://github.com/cordiverse/cordis/blob/main/packages/core/src/fiber.ts) at lines 78-85. This file also contains the `Fiber` class implementation, the `state` property tracking logic, and the transition methods that coordinate movement between the six lifecycle states.