Rules
Effect Doctor runs 118 rules, 93 from Effect TSGo and 25 from Effect Doctor. Every finding is a required fix.
Correctness 23
effect-doctor/no-multiple-callback-resumeerrorCall an Effect.callback continuation at most once on a straight-line path.
effect-doctor/no-mutation-after-unsafe-chunk-wraperrorPrevent direct mutation of arrays shared with Chunk.fromArrayUnsafe.
effect-doctor/no-run-sync-on-suspending-effecterrorAvoid synchronous runners for Effect constructors that are proven to suspend.
effect-doctor/no-throw-in-effect-generatorerrorKeep escaping exceptions out of confirmed Effect generator bodies.
effect/any-unknown-in-error-contextwarningDetects 'any' or 'unknown' types in Effect error or requirements channels
effect/class-self-mismatcherrorEnsures Self type parameter matches the class name in Context/Service/Tag/Schema classes
effect/duplicate-packagewarningWarns when multiple versions of an Effect-related package are detected in the program
effect/effect-fn-implicit-anyerrorMirrors noImplicitAny for unannotated Effect.fn, Effect.fnUntraced, and Effect.fnUntracedEager callback parameters when no outer contextual function type exists. Requires TS's noImplicitAny: true
effect/floating-effecterrorDetects Effect values that are neither yielded nor assigned
effect/floating-effect-in-vitesterrorDetects Effects returned from non-Effect-aware Vitest callbacks
effect/missing-effect-contexterrorDetects Effect values with unhandled context requirements
effect/missing-effect-errorerrorDetects Effect values with unhandled error types
effect/missing-layer-contexterrorDetects Layer values with unhandled context requirements
effect/missing-return-yield-starerrorSuggests using return yield* for Effects that never succeed
effect/missing-star-in-yield-effect-generrorDetects bare yield (without *) inside Effect generator scopes
effect/obsolete-match-importwarningWarns when importing @effect/match in projects targeting Effect v4, where Match is included directly in the effect package
effect/obsolete-schema-importwarningWarns when importing @effect/schema in projects targeting Effect v4, where Schema is included directly in the effect package
effect/outdated-apiwarningDetects usage of APIs that have been removed or renamed in Effect v4
effect/overridden-schema-constructorerrorPrevents overriding constructors in Schema classes which breaks decoding behavior
effect/promise-in-effect-successwarningDetects Promise types in Effect success channels where they are not awaited
effect/schema-literal-non-finiteerrorReports statically known non-finite numbers passed to Schema literal constructors
effect/schema-opaque-instance-membererrorDisallows instance members in classes extending Schema.Opaque
effect/unsafe-effect-type-assertionwarningDetects unsafe type assertions that narrow Effect, Stream, or Layer error or requirements channels
Resource safety 7
effect-doctor/no-duplicate-layer-factory-callwarningReuse a zero-argument Layer factory result within one composition graph unless the duplicate is explicitly fresh.
effect-doctor/no-long-lived-layer-acquisitionerrorFork provably long-lived work into the Layer scope instead of blocking acquisition.
effect-doctor/no-managed-runtime-in-effecterrorCreate ManagedRuntime only at a non-Effect host boundary.
effect-doctor/no-manual-sql-transactionerrorUse Effect SQL transaction ownership instead of sending transaction-control statements manually.
effect-doctor/no-network-in-sql-transactionerrorKeep direct HTTP work outside Effect SQL transaction effects.
effect-doctor/no-unbounded-concurrencyerrorRequire finite concurrency for Effect operations over collections that can grow.
effect-doctor/prefer-abort-signal-passthroughwarningForward Effect's AbortSignal when adapting a directly cancellable fetch promise.
Security 2
effect-doctor/no-unredacted-value-in-diagnosticerrorPrevent Redacted.value from exposing secrets directly inside diagnostic and telemetry sinks.
effect-doctor/prefer-config-redactederrorRedact statically named secret configuration values at construction.
Antipatterns 27
effect-doctor/diagnostic-suppressionwarningKeeps analyzer suppression directives visible for explicit review.
effect-doctor/no-inline-schema-compilewarningReuse closed Effect v4 schemas and parser adapters outside repeated function execution.
effect-doctor/no-module-mockswarningUse Effect service test layers instead of module mocks or method spies.
effect-doctor/no-sequential-effect-allwarningUse explicit sequencing instead of a serial Effect.all whose result is discarded.
effect-doctor/prefer-catch-tagwarningUse Effect.catchTag or Effect.catchTags for tagged failures.
effect-doctor/prefer-effect-fnwarningUse Effect.fn for a named generator operation.
effect-doctor/prefer-match-tags-exhaustivewarningUse Match.tagsExhaustive for a complete tagged-union transformation.
effect-doctor/prefer-predicate-is-taggedwarningUse Predicate.isTagged for combined tagged-value narrowing.
effect-doctor/require-named-effect-fnwarningRequire a stable operation name for Effect.fn.
effect/catch-unfailable-effectwarningWarns when using error handling on Effects that never fail
effect/effect-fn-iifewarningEffect.fn or Effect.fnUntraced is called as an IIFE; use Effect.gen instead
effect/effect-gen-uses-adapterwarningWarns when using the deprecated adapter parameter in Effect.gen
effect/effect-in-failurewarningWarns when an Effect is used inside an Effect failure channel
effect/effect-in-void-successwarningDetects nested Effects in void success channels that may cause unexecuted effects
effect/global-error-in-effect-catchwarningWarns when catch callbacks return global Error type instead of typed errors
effect/global-error-in-effect-failurewarningWarns when the global Error type is used in an Effect failure channel
effect/layer-merge-all-with-dependencieswarningDetects interdependencies in Layer.mergeAll calls where one layer provides a service that another layer requires
effect/lazy-effectwarningSuggests avoiding exported zero-argument functions and service members that lazily return Effect or Stream values
effect/lazy-promise-in-effect-syncwarningWarns when Effect.sync lazily returns a Promise instead of using an async Effect constructor
effect/leaking-requirementswarningDetects implementation services leaked in service methods
effect/multiple-effect-providewarningWarns against chaining Effect.provide calls which can cause service lifecycle issues
effect/prefer-unsafe-constructorwarningSuggests replacing Effect.runSync of a pure effect constructor with the synchronous *Unsafe variant exported by the same module
effect/return-effect-in-genwarningWarns when returning an Effect in a generator causes nested Effect<Effect<...>>
effect/run-effect-inside-effectwarningSuggests using Runtime or Effect.run*With methods instead of Effect.run* inside Effect contexts
effect/schema-sync-in-effectwarningSuggests using Effect-based Schema methods instead of sync methods inside Effect generators
effect/try-catch-in-effect-genwarningDiscourages try/catch in Effect generators in favor of Effect error handling
effect/unknown-in-effect-catchwarningWarns when catch callbacks return unknown instead of typed errors
Effect-native 18
effect-doctor/consistent-effect-fn-namewarningKeep unqualified Effect.fn span names consistent with their assigned function names.
effect-doctor/prefer-http-json-responsewarningUse Effect's JSON response constructor instead of stringifying into a text response.
effect-doctor/prefer-structured-log-datawarningPass structured values directly to Effect logging instead of serializing them first.
effect/abort-controller-in-effectwarningWarns when manually constructing AbortController inside Effect generators instead of using Effect.abortSignal
effect/crypto-random-uuidwarningWarns when using crypto.randomUUID() outside Effect generators instead of the Effect Crypto module
effect/crypto-random-uuid-in-effectwarningWarns when using crypto.randomUUID() inside Effect generators instead of the Effect Crypto module
effect/extends-native-errorwarningWarns when a class directly extends the native Error class
effect/global-console-in-effectwarningWarns when using console methods inside Effect generators instead of Effect.log/Logger
effect/global-date-in-effectwarningWarns when using Date.now() or new Date() inside Effect generators instead of Clock/DateTime
effect/global-fetch-in-effectwarningWarns when using the global fetch function inside Effect generators instead of the Effect HTTP client
effect/global-randomwarningWarns when using Math.random() outside Effect generators instead of the Random service
effect/global-random-in-effectwarningWarns when using Math.random() inside Effect generators instead of the Random service
effect/global-timers-in-effectwarningWarns when using setTimeout/setInterval inside Effect generators instead of Effect.sleep/Schedule
effect/instance-of-schemawarningSuggests using Schema.is instead of instanceof for Effect Schema types
effect/new-promisewarningWarns when constructing promises with new Promise instead of using Effect APIs
effect/node-builtin-importwarningWarns when importing Node.js built-in modules that have Effect-native counterparts
effect/process-envwarningWarns when reading process.env outside Effect generators instead of using Effect Config
effect/process-env-in-effectwarningWarns when reading process.env inside Effect generators instead of using Effect Config
Style 41
effect/acquire-release-disposablewarningSuggests Effect.acquireDisposable when Effect.acquireRelease only invokes the acquired resource's disposal protocol
effect/all-of-map-to-for-eachwarningSuggests using Effect.forEach instead of Effect.all over an effectful Array#map
effect/catch-all-tag-dispatch-to-catch-tagwarningSuggests Effect.catchTag or Effect.catchTags for catch-all handlers that re-fail unmatched tagged errors
effect/catch-all-to-map-errorwarningSuggests using Effect.mapError instead of Effect.catch + Effect.fail
effect/catch-chain-to-first-success-ofwarningSuggests Effect.firstSuccessOf for consecutive error-independent Effect.catch fallbacks when the error type is preserved
effect/catch-conditional-refail-to-catch-ifwarningSuggests Effect.catchIf, Effect.catchCauseIf, or Effect.catchTag for conditional catch handlers that re-fail their untouched input
effect/catch-die-to-or-diewarningSuggests using Effect.orDie instead of Effect.catch or Effect.catchAll with an identity-forwarding Effect.die handler
effect/catch-tag-to-catch-reasonwarningSuggests Effect.catchReason or Effect.catchReasons for handlers that re-fail unmatched reason._tag branches
effect/catch-to-ignorewarningSuggests using Effect.ignore or Effect.ignoreCause instead of Effect.catch/catchCause returning Effect.void
effect/catch-to-or-else-succeedwarningSuggests using Effect.orElseSucceed instead of Effect.catch + Effect.succeed
effect/effect-do-notationwarningSuggests using Effect.gen or Effect.fn instead of the Effect.Do notation helpers
effect/effect-fn-opportunitywarningSuggests using Effect.fn for functions that return an Effect
effect/effect-map-flattenwarningSuggests using Effect.flatMap instead of Effect.map followed by Effect.flatten in piping flows
effect/effect-map-voidwarningSuggests using Effect.asVoid instead of Effect.map(() => void 0), Effect.map(() => undefined), or Effect.map(() => {})
effect/effect-succeed-with-voidwarningSuggests using Effect.void instead of Effect.succeed(undefined) or Effect.succeed(void 0)
effect/flat-map-conditional-to-filter-or-failwarningSuggests Effect.filterOrFail or Effect.filterOrElse when Effect.flatMap conditionally passes its input through with Effect.succeed
effect/flat-map-to-mapwarningSuggests using Effect.map instead of Effect.flatMap when the callback only wraps its result with Effect.succeed
effect/map-some-to-as-somewarningSuggests using Effect.asSome instead of Effect.map when the mapper only wraps the success value with Option.some
effect/match-effect-to-map-bothwarningSuggests Effect.mapBoth when Effect.matchEffect only transforms the failure and success channels
effect/match-effect-to-matchwarningSuggests Effect.match or Effect.matchCause when both Effect.matchEffect handlers only return Effect.succeed
effect/missed-pipeable-opportunitywarningSuggests using .pipe() for nested function calls
effect/multiple-catch-tagwarningSuggests collapsing consecutive Effect.catchTag transformations into a single Effect.catchTags call when semantics stay equivalent
effect/nested-effect-gen-yieldwarningWarns when yielding a nested bare Effect.gen inside an existing Effect generator context
effect/option-match-to-from-optionwarningSuggests Effect.fromOption when Option.match or an Option tag conditional only converts Some to Effect.succeed and None to Effect.fail
effect/prefer-schema-type-propertywarningDisallows Schema.Schema.Type<typeof X> in favor of typeof X.Type
effect/prefer-succeed-some-or-nonewarningSuggests using Effect.succeedNone or Effect.succeedSome instead of wrapping Option.none or Option.some with Effect.succeed
effect/prefer-typed-schema-decoderwarningSuggests typed Schema decoders when the input is assignable to the schema's Encoded type
effect/provide-layer-succeed-to-provide-servicewarningSuggests providing inline Layer.succeed and Layer.effect services directly
effect/race-first-with-sleep-to-timeoutwarningSuggests Effect.timeoutOrElse when Effect.raceFirst has exactly one sleep- or delay-based timer arm
effect/redundant-map-errorwarningSuggests hoisting a repeated trailing Effect.mapError from every yield in an Effect generator
effect/redundant-or-diewarningSuggests hoisting a repeated trailing Effect.orDie from every yield in an Effect generator
effect/redundant-schema-tag-identifierwarningSuggests removing redundant identifier argument when it equals the tag value in Schema.TaggedClass/TaggedError/TaggedRequest
effect/run-of-exit-to-run-exitwarningSuggests using Effect.runPromiseExit instead of passing Effect.exit to Effect.runPromise
effect/schema-struct-with-tagwarningSuggests using Schema.TaggedStruct instead of Schema.Struct with _tag field
effect/sync-to-succeedwarningSuggests using Effect.succeed instead of Effect.sync when the thunk returns a constant value
effect/timeout-catch-tag-to-timeout-or-elsewarningSuggests dedicated timeout combinators instead of catching TimeoutError immediately after Effect.timeout
effect/unnecessary-effect-genwarningSuggests removing Effect.gen when it contains only a single return statement
effect/unnecessary-fail-yieldable-errorwarningSuggests yielding yieldable errors directly instead of wrapping with Effect.fail
effect/unnecessary-pipewarningRemoves pipe calls with no arguments
effect/unnecessary-pipe-chainwarningSimplifies chained pipe calls into a single pipe call
effect/unnecessary-typeof-typewarningSuggests replacing typeof Schema.Type style annotations with the matching named type when available