Lint rules
This appendix lists all lint rules that bino lint and bino build apply to your report manifests.
Lint rules check the content of your documents (semantic/business rules), while schema validation checks the structure.
All lint findings are currently treated as warnings and do not block builds.
| ID | Name | Description |
|---|---|---|
report-artefact-required | Report Artefact Required | At least one ReportArtefact document must be defined. |
artefact-layoutpage-required | Artefact LayoutPage Required | Each ReportArtefact must have at least one LayoutPage that matches its constraints and format. |
text-content-required | Text Content Required | Text components must have a non-empty spec.value field. |
dataset-required | Dataset Required | Table, ChartStructure, and ChartTime components must have a spec.dataset binding. |
page-layout-slots-used | Page Layout Slots Used | LayoutPage children count must match the expected slots for its pageLayout. |
card-layout-slots-used | Card Layout Slots Used | LayoutCard children count must match the expected slots for its cardLayout. |
Rule details
Section titled “Rule details”report-artefact-required
Section titled “report-artefact-required”Every bino report project needs at least one ReportArtefact document to define what PDF(s) to generate.
Example fix: Add a ReportArtefact manifest to your project:
apiVersion: bino.bi/v1
kind: ReportArtefact
metadata:
name: my-report
spec:
title: Monthly Sales Reportartefact-layoutpage-required
Section titled “artefact-layoutpage-required”Each ReportArtefact must have at least one LayoutPage that:
- Passes constraints — The page’s
metadata.constraintsmust match the artefact’s context (labels, spec, or mode). The linter checks bothbuildandpreviewmodes; a page is valid if it matches in either mode. - Matches format — The page’s
spec.pageFormatmust match the artefact’sspec.format. Both default toxgaif not specified.
Example problem:
# Artefact with format: a4
kind: ReportArtefact
metadata:
name: print-report
spec:
format: a4
---
# Page with default format (xga) won't match!
kind: LayoutPage
metadata:
name: page1
spec:
children: [...]Fix: Set spec.pageFormat: a4 on the LayoutPage.
text-content-required
Section titled “text-content-required”Text components are meant to display content. An empty spec.value produces blank output.
Example problem:
kind: Text
metadata:
name: header
spec:
value: "" # Empty!Fix: Provide meaningful content in spec.value.
dataset-required
Section titled “dataset-required”Data visualization components (Table, ChartStructure, ChartTime) need a dataset to display. Without spec.dataset, there’s nothing to render.
Example problem:
kind: Table
metadata:
name: sales-table
spec:
tableTitle: Sales Overview
# Missing dataset!Fix: Add a dataset reference:
spec:
dataset: sales-dataOr multiple datasets for charts:
spec:
dataset:
- revenue
- costspage-layout-slots-used
Section titled “page-layout-slots-used”Each LayoutPage must have exactly the number of children that match its pageLayout slot count. This rule is evaluated per artefact, counting only children that:
- Pass constraints — Children with
metadata.constraintsmust match the artefact’s context. - Have valid refs — Children with
refmust point to an existing document. Missing refs emit a warning and don’t count as slots. - Are renderable — Children must have either a
refor inlinespec.
Slot counts for predefined layouts:
| Layout | Slots |
|---|---|
full | 1 |
split-horizontal | 2 |
split-vertical | 2 |
2x2 | 4 |
3x3 | 9 |
4x4 | 16 |
1-over-2 | 3 |
1-over-3 | 4 |
2-over-1 | 3 |
3-over-1 | 4 |
For custom-template, the slot count is the number of distinct named area tokens in pageCustomTemplate:
# 3 slots: a, b, c
pageLayout: custom-template
pageCustomTemplate: |
"a a"
"b c"
# 2 slots: aa, bb
pageLayout: custom-template
pageCustomTemplate: |
"aa aa"
"bb bb"Example problem:
kind: LayoutPage
metadata:
name: dashboard
spec:
pageLayout: 2x2 # Expects 4 children
children:
- kind: Text
spec: { value: "Hello" }
- kind: Table
ref: sales-table
# Only 2 children, but 2x2 expects 4!Fix: Add children to fill all slots, or change pageLayout to match actual children count.
card-layout-slots-used
Section titled “card-layout-slots-used”Same as page-layout-slots-used, but for LayoutCard components. Each card’s cardLayout defines how many children it expects.
Example problem:
kind: LayoutCard
metadata:
name: summary-card
spec:
cardLayout: split-horizontal # Expects 2 children
children:
- kind: Text
spec: { value: "Only one child" }Fix: Add a second child or change cardLayout: full.
Adding custom rules
Section titled “Adding custom rules”The bino linter is designed for easy rule addition. Each rule has:
- ID: A unique identifier (e.g.,
naming-lowercase,reference-undefined-dataset). - Name: A short human-readable name.
- Description: An explanation of what the rule checks.
- Check function: The logic that inspects documents and returns findings.
Rules are registered in internal/report/lint/rules.go.
Suppressing warnings
Section titled “Suppressing warnings”Currently, lint warnings cannot be suppressed. Future versions may add per-rule or per-file suppression.
See also
Section titled “See also”- bino lint – CLI command for running lint.
- bino build – build command (runs lint by default).