Compliance errors
These entries cover the two exceptions in the NextPDF\Compliance\Exception
namespace. Both are thrown by the compliance subsystem: the canonical
clause-hash pipeline and the compliance lifecycle (the Document Compliance
Evidence cache, the audited-to-terminal promoter, and the cooldown observer).
Both classes are final and extend NextPdfException, which itself extends
\RuntimeException and implements ContextAwareExceptionInterface. Neither
subclass overrides getContext(), so both inherit the base implementation,
which returns an empty array. The diagnostic detail is carried in the exception
message, not in getContext(). Catch either type as
NextPdfException, or as \RuntimeException if you have existing handlers.
Clause-hash runtime requirements
Section titled “Clause-hash runtime requirements”ClauseHashRequirementException
Section titled “ClauseHashRequirementException”- When it is thrown. From
ClauseHash::compute()when the host PHP runtime is missing a hard requirement of the canonical clause-hash pipeline. Currently the only such requirement isext-intl, used for Unicode Normalization Form KC (NFKC) normalization. The single throw site raises the messageClauseHash requires ext-intl for NFKC normalisation. - Why it fails closed.
composer.jsonmandatesext-intl, so this fires only in a misconfigured downstream that packages NextPDF without intl. The pipeline refuses to compute a non-NFKC-normalized digest rather than silently emit a hash that is incompatible with every other clause-hash consumer. - Context.
getContext()returns an empty array. The cause is stated in the message. - Recovery. Operator action: install and enable the PHP
intlextension on the host, then retry. There is no in-code workaround; the normalized digest cannot be produced without it.
Compliance lifecycle failures
Section titled “Compliance lifecycle failures”ComplianceLifecycleException
Section titled “ComplianceLifecycleException”- When it is thrown. From the compliance lifecycle subsystem when a
structural invariant on
claims.jsonor its persistence pipeline is violated at runtime. Throw sites span the audited-to-terminal promoter, the cooldown observer, and the Document Compliance Evidence incremental cache. The concrete triggers are:- Malformed root document —
claims.jsondoes not decode to an object, orclaims.standardsis not a JSON object (for example,claims.json must decode to an object,claims.standards must be a JSON object,claims.json invalid JSON: <detail>). - Read failures —
claims.jsonis missing or unreadable (for example,claims.json not found at: <path>,claims.json unreadable at <path>). - Atomic-write I/O failures in the persistence pipeline — temp open,
flock, short write,fflush, atomicrename, and sidecar write (for example,tmp open failed at <path>,tmp flock failed at <path>,tmp write short for <path>,tmp fflush failed at <path>,atomic rename failed for <path>,sha256 sidecar write failed at <path>). - Encoder-side failures —
json_encode()rejects the outgoing payload (for example,claims.json encode failed: <detail>). - Evidence-cache bootstrap failures — the incremental cache cannot create
or write its root directory (for example,
IncrementalEvidenceCache: cannot create rootDir <path>,IncrementalEvidenceCache: write failed for <path>,IncrementalEvidenceCache: rename failed for <path>). - Internal invariant breaches — for example a
gmdate produced empty timestamporfqClauseId: empty clauseKey.
- Malformed root document —
- Why it exists. This is a domain-typed replacement for the previous use of
\RuntimeExceptionin the lifecycle and cache code. It does not change the runtime contract, becauseNextPdfExceptionalready extends\RuntimeException; existingcatch (\RuntimeException $e)clauses keep working. - Context.
getContext()returns an empty array. The offending path and the specific failure are named in the message; JSON-decode and encode failures also chain the underlying\JsonExceptionas the previous exception, so readgetPrevious()for those. - Recovery.
- For shape and read errors, this is an operator action: inspect
claims.jsonat the path named in the message, confirm it is well-formed JSON whose root andstandardsmember are objects, and confirm it is present and readable. - For atomic-write and cache-bootstrap errors, check the target directory’s existence, permissions, and free space, then retry.
- For encoder-side failures, this is a developer action: the payload handed to
json_encode()is not encodable. Capture the chained previous exception and the message for a defect report.
- For shape and read errors, this is an operator action: inspect