Skip to content

Fix databook validate: ESM require crash, silent engine fallback, error masking#1

Merged
kurtcagle merged 1 commit into
mainfrom
fix/validate-cjs-require
Jul 8, 2026
Merged

Fix databook validate: ESM require crash, silent engine fallback, error masking#1
kurtcagle merged 1 commit into
mainfrom
fix/validate-cjs-require

Conversation

@kurtcagle

Copy link
Copy Markdown
Owner

Fixes three stacked issues in commands/validate.js, found and diagnosed by Ben Wortley while running SHACL validation for the UN-GGCE QA pass:

  1. Crash: executeLocalValidation() used bare CommonJS require('fs') / require('os') / require('path'), but the package is "type": "module" — throws require is not defined the moment validation reaches the local engine. --dry-run skips this path, which is why it went unnoticed.
  2. Fallback logic: executeValidation() had if (jenaShacl || !endpointOpt) — when no engine is installed and no --endpoint is given, it still called local validation with a null engine instead of failing informatively.
  3. Error masking: the catch around execFileSync returned e.message as the result, so past bug Fix databook validate: ESM require crash, silent engine fallback, error masking #1, a missing engine would come back looking like a SHACL report instead of an error.

Fix hoists the three requires to top-level ESM imports and dies with a clear message when no engine is found and no --endpoint is given.

Ben applied this fix locally, put pyshacl behind it, and re-ran the full UN-GGCE suite — all six DataBooks (capability-maturity, the four workflow DataBooks, satellite-orbits) validate CONFORMS against ggsc-shacl-all.

Also worth noting for a follow-up: a blank line between a <!-- databook:id: ... --> annotation and its code fence makes the block anonymous, and anonymous blocks get PUT to the default graph sequentially, each replacing the last. Bit the UN-GGCE QA pass twice (satellite-orbits in June, capability-maturity this week). Worth the parser either tolerating the blank line or warning loudly when a block resolves to the default graph — not addressed in this PR.

…or masking

- Hoist require('fs')/require('os')/require('path') in executeLocalValidation
  to top-level ESM imports (package is type:module; bare require() throws).
- executeValidation no longer falls into executeLocalValidation with a null
  engine when neither a local engine nor --endpoint is available; dies with
  a clear message instead.
- executeLocalValidation's catch no longer returns e.message as if it were
  a SHACL report when execFileSync fails with no captured stdout.

Reported and diagnosed by Ben Wortley (UN-GGCE QA pass); confirmed against
UN-GGCE suite (capability-maturity, four workflow DataBooks, satellite-orbits)
all validating CONFORMS against ggsc-shacl-all with the fix applied.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant