Effect-native diagnostics guide you toward the Effect ecosystem’s purpose-built APIs for common operations — HTTP requests, JSON parsing, schema validation, and more. All rules in this category are off by default (except preferSchemaOverJson which is a suggestion), so you opt in to the ones that fit your project’s strictness requirements.
All rules in this category are ➖ off by default or 💡 suggestion level. Enable them via diagnosticSeverity in your plugin config.
extendsNativeError
Severity: ➖ off by default · V3/V4: ✓ / ✓
Warns when a class directly extends the native JavaScript Error class. Native Error subclasses are untagged and indistinguishable at the type level in Effect’s failure channel. Using Data.TaggedError instead gives your errors a _tag discriminant that enables precise Effect.catchTag handling.
import { Data } from "effect"
// ❌ Violation — native Error is untagged
class DatabaseError extends Error {
constructor(message: string) {
super(message)
this.name = "DatabaseError"
}
}
// ✅ Correct — tagged error enables precise error handling
class DatabaseError extends Data.TaggedError("DatabaseError")<{
message: string
}> {}
// Now you can handle it precisely:
// Effect.catchTag("DatabaseError", (e) => ...)
To enable:
{ "diagnosticSeverity": { "extendsNativeError": "warning" } }
globalFetch
Severity: ➖ off by default · V3/V4: ✓ / ✓
Warns when the global fetch function is used instead of the Effect HTTP client. The global fetch is a Promise-based API that throws on network errors and returns responses that require manual error checking. The Effect HTTP client integrates errors into the typed error channel.
import { Effect } from "effect"
import { HttpClient } from "@effect/platform"
// ❌ Violation — global fetch, errors are untyped
const getUser = Effect.gen(function* () {
const response = await fetch("/api/users/1") // Promise, not Effect
return response.json()
})
// ✅ Correct — Effect HTTP client with typed errors
const getUser = Effect.gen(function* () {
const client = yield* HttpClient.HttpClient
const response = yield* client.get("/api/users/1")
return yield* response.json
})
To enable:
{ "diagnosticSeverity": { "globalFetch": "warning" } }
instanceOfSchema
Severity: ➖ off by default · Fix: 🔧 · V3/V4: ✓ / ✓
Suggests using Schema.is instead of the instanceof operator for Effect Schema types. instanceof does not account for Schema’s structural validation and decoded representations, while Schema.is performs a proper type-guard check that respects the schema’s constraints.
import { Schema } from "effect"
const UserSchema = Schema.Struct({ id: Schema.String, name: Schema.String })
type User = Schema.Schema.Type<typeof UserSchema>
declare const value: unknown
// ❌ Violation — instanceof does not validate schema constraints
if (value instanceof Object && "id" in value) {
// not a proper schema check
}
// ✅ Correct — Schema.is performs a proper type-guard
const isUser = Schema.is(UserSchema)
if (isUser(value)) {
// value is User here, fully type-safe
}
The quick fix replaces the instanceof check with Schema.is(...) automatically.
To enable:
{ "diagnosticSeverity": { "instanceOfSchema": "warning" } }
nodeBuiltinImport
Severity: ➖ off by default · V3/V4: ✓ / ✓
Warns when you import Node.js built-in modules (like fs, path, crypto) that have Effect-native counterparts in @effect/platform. The Effect platform modules provide the same functionality with typed errors and Effect integration.
// ❌ Violation — importing Node.js built-in directly
import * as fs from "node:fs"
import * as path from "node:path"
// ✅ Correct — use Effect platform counterparts
import { FileSystem } from "@effect/platform"
import { NodeFileSystem } from "@effect/platform-node"
const program = Effect.gen(function* () {
const fs = yield* FileSystem.FileSystem
const content = yield* fs.readFileString("./config.json")
return content
})
To enable:
{ "diagnosticSeverity": { "nodeBuiltinImport": "warning" } }
preferSchemaOverJson
Severity: 💡 suggestion · V3/V4: ✓ / ✓
Suggests using Effect Schema for JSON operations instead of JSON.parse and JSON.stringify. JSON.parse throws on invalid input and returns any; Effect Schema provides type-safe parsing with proper error handling through the effect error channel.
import { Effect, Schema } from "effect"
const UserSchema = Schema.Struct({ id: Schema.String, name: Schema.String })
// ❌ Violation — JSON.parse returns any and throws on error
const parseUser = (raw: string) => {
const data = JSON.parse(raw) // any, can throw
return data as User
}
// ✅ Correct — Schema.decode provides typed parsing with Effect errors
const parseUser = (raw: string) =>
Effect.gen(function* () {
const json = yield* Effect.try({
try: () => JSON.parse(raw),
catch: (e) => new ParseError({ cause: e })
})
return yield* Schema.decode(UserSchema)(json)
})