# Error catalog

> WestCoast Charts 1.1.5, release, public Core release, on npm. HTML: https://westcoast-charts.com/docs/errors/ · Index for agents: https://westcoast-charts.com/llms.txt · Source: library docs, commit 95f093ba

`WestCoastCharts.validate(options)` (module `west-coast-charts/agent/validate`) checks a
chart options object against the JSON Schema generated from our own `types/*.d.ts`
(`dist/schema/wcc-options.schema.json`, draft 2020-12, versioned as `x-wcc-version`).
The result is meant for people and for agents (LLMs, the `wcc` CLI): every issue is
structured, names the exact path, says what is wrong, and carries a machine-applicable fix
when one is known.

## Result

```js
{
  ok: false,            // no issue of severity 'error'
  errors: 2,
  warnings: 1,
  exitCode: 4,          // highest-priority exit code of all issues (see below), 0 when ok
  schemaVersion: '1.0.0',
  issues: [ /* WccIssue */ ]
}
```

## Issue

| field | type | meaning |
|---|---|---|
| `kind` | `'unknown_option' \| 'type_mismatch' \| 'invalid_value' \| 'deprecated' \| 'license_required'` | what is wrong |
| `severity` | `'error' \| 'warning'` | errors make `ok` false; warnings never do |
| `path` | string | dotted path with array indices: `series[0].data`, `plotOptions.bar.borderRadius` |
| `pointer` | string | the same as RFC 6901 JSON Pointer: `/series/0/data` |
| `message` | string | one precise sentence: what was found and what is allowed |
| `hint` | string | what to do instead (`Did you mean legend.show?`) |
| `suggestion` | string \| null | best replacement: a path (unknown/deprecated), a value (invalid/type), a URL (license) |
| `alternatives` | string[] | up to 3 further candidates, best first |
| `fix` | `{op:'rename',from,to,value?}` \| `{op:'set',path,value}` \| `{op:'remove',path}` \| null | apply with `applyFixes(options, issues)` |
| `exitCode` | number | the CLI exit code this issue alone maps to (warnings: 0) |

## Kinds

| kind | severity | exit code | when | example |
|---|---|---|---|---|
| `unknown_option` | error (warning inside open objects such as series items, `chart.events` handlers or other index-signature types) | 2 | a key the schema does not know. Suggestions come from known aliases (Chart.js, Highcharts, ECharts, Plotly, Vega-Lite, older ApexCharts habits), edit distance, casing, and a global key index that finds options at the wrong place (preferring `plotOptions.<chart.type>`) | `legend.enabled` → `legend.show`; `xAxis` → `xaxis`; `chart.aggregate` (radialColumn) → `plotOptions.radialColumn.aggregate` |
| `type_mismatch` | error | 2 | right key, wrong JSON type. Coercions are offered where they are lossless (`"12"` → `12`, `"true"` → `true`, `true` for an object option → `{ enabled: true }` / `{ show: true }`, a string for a string array → `[string]`) | `colors: '#f00'` → `['#f00']`; `chart.animations: false` → `{ enabled: false }` |
| `invalid_value` | error | 2 | the value is not one of the allowed literals | `stroke.curve: 'spline'` → `'smooth'`; `chart.type: 'column'` → `'bar'` |
| `deprecated` | error when the option has no effect any more (older ApexCharts keys), warning when it is `@deprecated` in our types but still honoured | 2 / 0 | the option was replaced; the fix translates the value where possible | `plotOptions.bar.endingShape: 'rounded'` → `plotOptions.bar.borderRadius: 4` |
| `license_required` | error for a premium `chart.type`, warning for premium-only options under `plotOptions` (ignored without premium) | 4 / 0 | only when premium is known to be absent (`validate(o, { premium: false })`; the chart-creation hook detects `west-coast-charts/premium` itself) | `chart.type: 'sankey'` → install `west-coast-charts/premium`, [card-free 30-day trial](https://westcoast-charts.com/pricing/#trial) |

## CLI exit codes

Shared by the validator (`result.exitCode`, `issue.exitCode`, `exitCodeOf(result)`) and the `wcc` CLI.

| code | name (`EXIT`) | meaning | from the validator |
|---|---|---|---|
| 0 | `ok` | success; warnings may exist | `ok: true` |
| 1 | `internal` | internal error (bug, crash, unreadable schema) | validator threw |
| 2 | `usage` | schema / usage error: invalid options or arguments | `unknown_option`, `type_mismatch`, `invalid_value`, `deprecated` (error) |
| 3 | `notFound` | a referenced thing does not exist (file, chart id, series, template) | CLI only |
| 4 | `license` | a premium feature is used without premium / without a valid key | `license_required` (error) |
| 5 | `conflict` | the operation conflicts with the current state (stale revision, concurrent edit, option combination that cannot both hold) | CLI only |
| 6 | `confirmation` | a destructive or billable step needs explicit confirmation (`--yes`) | CLI only |

When several issues are present, `result.exitCode` is the most specific one: 4 before 2, 2 before 0.
An agent should fix all issues of a run, not just the first; `applyFixes` applies every `fix` it can.

## At chart creation

`chart.validate: 'warn' | 'error' | 'off'` (default `'warn'`) once the module is loaded
(`import 'west-coast-charts/agent/validate'` installs itself; it is never part of core):

* `'warn'`: one `console.warn` listing every issue with its hint; the chart renders.
* `'error'`: `console.error` and `chart.render()` / `updateOptions()` reject with an `Error`
  whose `code` is `'WCC_INVALID_OPTIONS'`, `.issues` the issue list and `.exitCode` the exit code.
* `'off'`: no check.

## Example

```js
import { validate, applyFixes } from 'west-coast-charts/agent/validate'

const r = validate({ chart: { type: 'bar' }, legend: { enabled: false }, stroke: { curve: 'spline' } })
// r.exitCode === 2
// r.issues[0]: { kind: 'unknown_option', path: 'legend.enabled', suggestion: 'legend.show',
//                hint: 'Did you mean legend.show?', fix: { op: 'rename', from: 'legend.enabled', to: 'legend.show' } }
// r.issues[1]: { kind: 'invalid_value', path: 'stroke.curve', suggestion: 'smooth', fix: { op: 'set', path: 'stroke.curve', value: 'smooth' } }
const fixed = applyFixes(options, r.issues) // validate(fixed).ok === true
```
