Appearance
Validate and test a plugin
What you're doing
Catching mistakes before you publish. The SDK runs the same checks the platform runs at install time, so a clean local run means a clean install. Three commands, cheapest first.
The complete sequence
bash
erp schema validate spk-assembly/metadata/entities/oeq_equipment.json --schema entity-definition
erp plugin validate spk-assembly
erp plugin test spk-assemblyPlus, over MCP, the semantic linter directly:
erp_lint_plugin_semantics {"pluginDir": "developer-docs/tutorial/example-plugin/spk-assembly"}Line by line
erp schema validate <file> --schema <name>
Checks one JSON file against one schema. Use it while authoring a single artifact. Fast, no backend needed.
OK — spk-assembly/metadata/entities/oeq_equipment.json matches schema "entity-definition"erp plugin validate <dir>
Validates every page in the plugin against the page contract and the live block registry (does each blockType exist, does each property it sets actually belong to that block).
validated 3 page(s) — cleanerp plugin test <dir>
Runs plugin validate plus the semantic lints — the checks that catch the "looks fine, silently broken" class of bug:
Plugin Tests
────────────────────────────────────────
✓ page:equipment-catalog.json
✓ page:equipment-checkout.json
✓ page:equipment-register.json
✓ plugin.json:valid-json
1 passed, 0 failed, 0 semantic warning(s), 3 skippedThe semantic lint codes — what each one catches
| Code | Catches | Fix |
|---|---|---|
| PAGE-DS-001 | a page has a core.grid but metadata.dataSource is missing or doesn't match any metadata/provider/*.json name — the "0 rows, no error" bug | see Wire a page's data |
| DS-001 | a Data Service filter compares a value of the wrong type (e.g. a string against a numeric column) | fix the filter, or set valueType |
| I18N-001 | a page references an i18n key with no entry in metadata/i18n/en.json (or a placeholder value) | add the key — see Add i18n |
| SEED-001 | a metadata/seed-data/*.json targets an entity the plugin doesn't ship and that isn't a known shared config entity, or keyFields look non-unique | ship the entity, or fix the key |
| JOB-001 | a new bespoke ErpJobContribution Java class where a generic sweep engine + JSON config would do | delete the Java, add a config row — see the job guides |
| page-semantic-lint | a foreign-key field bound to a plain text/number input instead of core.lookup; decorative filters that aren't wired | use core.lookup; wire the filter to externalFilter |
These are warnings, not hard failures — review each. But the platform's install-time equivalents of PAGE-DS-001 / I18N-001 / SEED-001 do block a bad install, so treat them as errors.
Wire it into CI
The docs in this tree keep every example honest with a runner that validates every artifact and runs erp plugin test:
bash
node developer-docs/examples/test-examples.mjsvalidating tutorial module artifacts against live schemas...
ok tutorial/entities/oeq_equipment.json
...
running `erp plugin test` on the tutorial module...
4 passed, 0 failed, 0 semantic warning(s), 3 skipped
All examples valid.Run it in CI on every change to developer-docs/. A broken example fails the build.
How to verify it worked
A green erp plugin test and a green test-examples.mjs. That's the bar for "safe to publish".
Common mistakes
| Symptom | Cause | Fix |
|---|---|---|
erp plugin validate says "no page JSON found" | you pointed it at the plugin root, not spk-assembly | pass <plugin>/spk-assembly |
erp schema validate fails on a page file | page files are wrapped; --schema page checks the inner contract | rely on erp plugin validate / test for pages |
| lint clean locally, install still fails | a check the platform runs that the SDK doesn't (rare) | read the install error; report it |
erp plugin test skips security-rule-scan etc. | those need extra inputs | fine for a JSON-only plugin |
What to read next
- Publish and upgrade a plugin
- Wire a page's data
- Troubleshooting: known gotchas