This version is still in development and is not considered stable yet. For the latest stable version, please use fluent-tooling 0.0.1!

JSON diagnostics protocol

ftl-lint --format json is the stable interface for editor and tool integration. Human-readable output may evolve independently; integrations should consume this protocol instead.

Invocation and streams

Pass files or standard input exactly as in human mode:

ftl-lint --format json locales/pl/messages.ftl
ftl-lint --format json - < locales/pl/messages.ftl

A valid invocation writes one JSON document to standard output. Invocation and I/O errors go to standard error. The JSON document is compact; examples in this guide are formatted for readability.

Schema version 1

{
  "schema_version": 1,
  "diagnostics": [
    {
      "path": "locales/pl/messages.ftl",
      "severity": "error",
      "code": "E0003",
      "message": "expected token `}`",
      "labels": [
        {
          "primary": true,
          "message": "unexpected `?` inside the placeable",
          "span": {
            "start": { "byte": 30, "line": 0, "column": 26 },
            "end": { "byte": 31, "line": 0, "column": 27 }
          }
        }
      ],
      "notes": [],
      "help": ["close the placeable before `?`"]
    }
  ]
}

The top-level object contains:

Field Type Meaning

schema_version

integer

Protocol version; currently 1

diagnostics

array

Zero or more diagnostic objects

Each diagnostic contains:

Field Type Meaning

path

string

Input path, or <stdin> for standard input

severity

string

error or warning

code

string

Stable Fluent or project lint code

message

string

Diagnostic summary

labels

array

Labeled source spans

notes

array of strings

Supporting context

help

array of strings

Suggested actions

Every label contains:

Field Type Meaning

primary

boolean

Whether this is the diagnostic’s primary label

message

string

Explanation attached to the span

span

object

Half-open source range with start and end positions

The diagnostics, labels, notes, and help arrays are always present, including when they are empty.

Source positions

Each position contains three zero-based values:

Field Meaning

byte

UTF-8 byte offset from the beginning of the input

line

Line number

column

Unicode scalar-value offset from the beginning of the line

Spans are half-open: start is inclusive and end is exclusive. Empty spans have identical start and end positions. LF, CRLF, and lone CR each advance the line once and reset the column to zero.

Columns count Unicode scalar values, not bytes, UTF-16 code units, grapheme clusters, or display cells. Consumers that index UTF-8 source can use byte; editors should translate line and column into their native position type.

Exit and error behavior

The JSON format preserves the command’s normal exit statuses:

Result Standard output Standard error Status

All inputs clean

Empty diagnostics document

Empty

0

Diagnostics found

Diagnostics document

Empty

1

An input cannot be read

Diagnostics from successfully read inputs

I/O error

2

Invalid invocation

No JSON document

Error and usage

2

An I/O failure may therefore produce an empty or partial diagnostics document. Consumers must check the process status and standard error as well as parse standard output.

Compatibility

Consumers should reject documents whose schema_version they do not support. Breaking field or position changes require a new schema version. Consumers should ignore unknown fields within a supported version so compatible fields can be added later.