effx
Diagnostics

Diagnostics

Diagnostic data, severity policies, and the generated code catalogue.

A diagnostic reports a problem in your source or your project. It is data, not an exception. A diagnostic with severity error blocks generation. Nothing is thrown.

Source: packages/compiler/src/Diagnostic.ts, packages/compiler/src/CompilerFault.ts, packages/cli/src/report.ts, docs/specs/0001-compiler-kernel.md.

Shape

packages/compiler/src/Diagnostic.ts (shape)
interface Diagnostic {
  readonly code: string
  readonly severity: "error" | "warning" | "info"
  readonly message: string
  readonly location?: { file: string; line: number; col: number }
  readonly related?: ReadonlyArray<Diagnostic>
}
FieldTypeRule
codestringnumeric EFFX#### or namespaced EFFX[<package>]/#### identifier; validated by DiagnosticCode
severityerror, warning or infoSeverity schema
messagestringhuman-readable text
locationLocation, optional{ file, line, col } with integer line and col
relatedDiagnostic array, optionalnested diagnostics, for example the other side of a conflict

Diagnostic is an Effect Schema, so it serializes. Helpers: error(code, message, location?), warning(code, message, location?) and hasErrors(diagnostics).

What severities do

SeverityBlocks generationCLI exit
erroryes. generate is skipped and effx build writes nothing.1
warningno0
infono0

Some codes change severity with a setting. For example --strict-access raises the missing-access warning to an error (spec 0006).

Diagnostics are data

Every pipeline stage returns a StageResult: an optional value plus the diagnostics it found. Diagnostics accumulate across stages. The frontend's own diagnostics also travel as data in Collected.

TypeShape
StageResult<A>{ value: Option<A>, diagnostics: Diagnostic[] }
CompileResult.diagnosticsevery diagnostic from every stage, in stage order

CompilerFault is a different thing. It is a tagged error reserved for IO and invariant failures, such as an unreadable project, a broken cache or a generator bug. A source problem is never a fault (invariant 11, The invariant).

Where you see diagnostics

PlaceDetail
Terminaleffx check and effx build print them grouped by file, then a summary line (effx check)
.effx/manifest.jsoneffx build stores all diagnostics, with related, in the diagnostics field (effx build)
Watch terminaleffx dev prints a full batch and counts for each completed cycle
Editoreffx lsp publishes replacements only for open documents; unlocated findings use logs

Terminal line format:

<code> <severity padded to 8> <message>  <file>:<line>:<col>

Diagnostics without a location omit the file suffix and are listed last under (no location). inspect and graph do not print diagnostics.

Specifications

The bundled registry documents each diagnostic code. These specs define the compiler contracts:

SpecTitle
0001-compiler-kernelCompiler kernel
0002-source-frontendRuntime surface and TypeScript source frontend
0003-cli-and-vertical-sliceCLI and vertical slice
0005-http-contract-extensionHTTP contract extension
0006-access-contract-extensionAccessContract and required guard bindings
0007-client-and-foldkitGenerated client and Foldkit command adapter
0010-target-profiles-and-emit-modesTarget profiles, declarations and split HTTP emit modes
0013-group-defaultsGroup defaults and dense HTTP declarations
0022-persistence-portsPersistence port declarations and adapter conformance

Diagnostic code registry

Read the diagnostic code registry for each code, its severity policy, and concrete repairs.

Use effx explain <code> for the same explanation offline. The catalogue comes from the bundled registry, not copied tables.

effx explain EFFX2504
effx explain 'EFFX[@acme/payments]/0001' --config ./effx.config.ts

Without --config, explain uses only the bundled registry. It does not discover or evaluate effx.config.ts, even for unknown codes.

With --config <path>, explain loads that config and its imports, then validates its extension entries. It does not compile project sources. An invalid explicit config fails even for a bundled code. Project and generation flags, such as --project and --out-dir, are not accepted.

Quote namespaced codes so that the shell does not treat brackets as patterns. Codes are case-sensitive; numeric shorthand is not accepted.

Extension authors supply entries through Extension.diagnosticEntries or the diagnosticEntries option of implement. The shared @effx/diagnostics renderer can generate a separate catalogue for those entries.

On this page