FiberFailure: Error: Defect
What causes this
In Effect-TS, a “Defect” is an unexpected, unhandled error — something your program didn’t anticipate. Unlike expected errors (which you model in the error channel), defects are bugs. They crash the fiber because there’s no handler for them.
Common causes:
- Throwing a raw JavaScript error inside an Effect without wrapping it
- A promise rejection that wasn’t caught by
Effect.tryPromise - Accessing a property on
undefinedinside an Effect pipeline - A third-party library throwing unexpectedly
Fix 1: Use Effect.tryPromise for async operations
import { Effect } from 'effect';
// ❌ Raw promise — unhandled rejection becomes a Defect
const program = Effect.promise(() => fetch('/api'));
// ✅ tryPromise catches rejections as expected errors
const program = Effect.tryPromise({
try: () => fetch('/api'),
catch: (error) => new FetchError({ cause: error }),
});
Fix 2: Handle all errors with catchAll
const program = Effect.tryPromise(() => fetch('/api')).pipe(
Effect.flatMap((res) => Effect.tryPromise(() => res.json())),
Effect.catchAll((error) =>
Effect.succeed({ fallback: true, error: String(error) })
)
);
Fix 3: Use Effect.gen with proper error handling
const program = Effect.gen(function* () {
const response = yield* Effect.tryPromise(() => fetch('/api'));
if (!response.ok) {
return yield* Effect.fail(new ApiError({ status: response.status }));
}
const data = yield* Effect.tryPromise(() => response.json());
return data;
}).pipe(
Effect.catchTag('ApiError', (e) =>
Effect.succeed({ error: `API returned ${e.status}` })
),
Effect.catchAll((e) =>
Effect.succeed({ error: 'Unexpected error', details: String(e) })
)
);
Fix 4: Catch defects specifically
If you want to recover from defects (not just expected errors):
import { Effect, Cause } from 'effect';
const program = myEffect.pipe(
Effect.catchAllCause((cause) => {
if (Cause.isFailure(cause)) {
// Expected error
return Effect.succeed({ type: 'expected-error' });
}
// Defect — log it and recover
console.error('Defect:', Cause.pretty(cause));
return Effect.succeed({ type: 'defect-recovered' });
})
);
Related resources
How to prevent it
- Always use
Effect.tryPromiseinstead ofEffect.promisefor operations that can fail - Model your errors as tagged classes so you can handle them with
catchTag - Use
Effect.sandboxduring development to see the full cause of failures - Add a top-level
catchAllCausein your main program to log defects instead of crashing silently