---
name: guide-lint
description: Run a pre-publish format check on a file so the share previews correctly. CLI subcommand and REST API.
---

# Lint a file before publishing

Anchorify surfaces authoring warnings ("your slide deck frontmatter isn't going to be detected", "this CSV is semicolon-delimited", "this JSON has a syntax error") on three surfaces:

1. **Share-render owner banner** — visible only to you (the share's org admin) inline above the rendered share.
2. **CLI publish** — printed to stderr after a successful publish.
3. **Lint API** — pre-publish check via `POST /api/v1/lint`.

All three use the same analyzer, so the warnings are consistent across surfaces.

## CLI: `anchorify lint <file>`

```bash
anchorify lint deck.md
```

Returns one of:

- **Exit 0** with `ok — deck.md lints clean as slides_marp` when there are no issues.
- **Exit 0** with one or more `warn`/`info` lines when the file will preview but is worth tightening up.
- **Exit 1** with one or more `error` lines when the file will look broken to recipients.

Use `--type` to lint as a specific content type when the filename doesn't match:

```bash
anchorify lint data.txt --type csv
```

## API: `POST /api/v1/lint`

Auth: per-user bearer token (same as other write endpoints). Request body:

```json
{
  "content": "---\nmarp: true\n---\n# Slide one",
  "filename": "deck.md",
  "content_type": "slides_marp"
}
```

- `content` (required): the file contents as a string.
- `filename` (optional): used for filename-extension content-type detection.
- `content_type` (optional): override; one of `markdown`, `code`, `json`, `yaml`, `csv`, `tsv`, `html`, `slides_marp`, `slides_reveal`.

Response (200):

```json
{
  "effective_content_type": "slides_marp",
  "warnings": [
    {
      "kind": "slide_deck_no_separators",
      "severity": "warn",
      "message": "This deck has no `---` slide separators after the frontmatter — everything will render as a single slide.",
      "doc_url": "/docs/guide-slides#slide-separators",
      "location": { "line": 4 }
    }
  ]
}
```

`effective_content_type` is the type the publish would actually use — handy when the API caller wants to confirm the sniffer's decision.

`warnings` is always present (an empty array means the file is clean).

## Warning kinds

| kind                              | severity | What it means |
| --------------------------------- | -------- | ------------- |
| `empty`                           | warn     | Content is empty / whitespace only. |
| `slide_frontmatter_unrecognized`  | error    | File contains `marp: true` / `reveal: true` but the frontmatter is malformed (e.g. no closing `---`, blocked by content before the opener). |
| `slide_deck_no_separators`        | warn     | Marp/reveal deck with no `---` slide separators — renders as a single slide. |
| `unclosed_frontmatter`            | warn     | File opens with `---` but the block never closes; renders as `<hr>` followed by content. |
| `json_parse_failed`               | error    | JSON is unparseable (after trailing-comma recovery). Pretty-print won't fire. |
| `csv_likely_wrong_delimiter`      | info     | File is stored as CSV but the header row looks semicolon/tab-delimited. The renderer auto-detects, but the file isn't portable. |
| `markdown_looks_like_html`        | warn     | Content begins with `<!DOCTYPE>` / `<html>`. Switch to `--type html` so DOMPurify sanitizes. |
| `code_no_language`                | info     | Code with no filename → no language detection → no syntax highlighting. |
| `binary_under_text_type`          | error    | NUL bytes detected in content stored as a text type. Re-upload via the web form. |

## Severity meanings

- **error** — the file will look broken to recipients (raw frontmatter visible, JSON parse failed, etc.). Fix before publishing.
- **warn** — the file might look subtly wrong. Renders but worth a look.
- **info** — the file renders correctly; this is a portability/best-practice note.

## What the lint does NOT check

- The actual rendered output (we don't run Marp or marked just to verify).
- Spelling, grammar, broken links inside the content.
- File size (the upload form enforces that separately).
- Whether the filename + slug are clean (slug rules are enforced at publish time).

## Next steps

- [Slide decks](/docs/guide-slides) — fix the most common slide-deck warning.
- [Content types and rendering](/docs/guide-content-types) — what each renderer expects.
- [Command-line](/docs/guide-cli) — the rest of the CLI surface.
