Pulp Engine v0.35.0 — Release Notes
This release closes two production-trust gaps: asset-binary store health is now first-class in the readiness probe, and private-mode renders no longer silently produce documents with broken images when a referenced asset is missing or unreadable.
What changed
1. Asset-binary store health in readiness probe (breaking: /health/ready response shape)
GET /health/ready now checks both the template store and the asset binary store.
Each check runs independently with its own 2-second timeout and is reported separately,
giving operators precise per-component diagnosis.
Before:
{ "status": "ok", "checks": { "storage": "ok" } }
After:
{ "status": "ok", "checks": { "storage": "ok", "assetBinaryStore": "ok" } }
The status field remains "ok" / "degraded" and the HTTP response code remains
200 / 503 — no change to the top-level contract. The checks object gains
assetBinaryStore and both fields now support "timeout" in addition to "ok" /
"error".
If you have monitoring that reads individual checks fields, add assetBinaryStore
to your health dashboards.
Backed by a new ping() method on IAssetBinaryStore:
- Filesystem store:
fs.access(ASSETS_DIR, R_OK)— cheap, no write - S3 store:
HeadBucketcommand — same as the startup probe, brief error message
2. Fail-closed asset inlining for production renders (breaking: behavior change)
In private mode (ASSET_ACCESS_MODE=private), inlineAssets() previously swallowed
all per-asset errors silently, leaving the original /assets/filename URL in the
rendered HTML. Since Puppeteer renders the HTML in isolation (no auth headers), this
URL was unreachable, producing a PDF or HTML document with broken images — with no
error, no log, and no failed status code.
New behavior:
| Endpoint | Policy | Behavior on missing/unreadable asset |
|---|---|---|
POST /render (PDF) | Strict | Non-2xx failure with clean message |
POST /render/html | Strict | Non-2xx failure with clean message |
POST /render/preview/pdf | Strict | Non-2xx failure with clean message |
POST /render/preview/html | Soft-fail | 200 with original URL preserved + warn log |
The error message in strict mode lists only the affected filenames:
Failed to inline required assets: logo.png, header.jpg
Backend error details (ENOENT, NoSuchKey, etc.) are emitted to structured logs
at warn level for operator diagnosis but are not surfaced in API responses.
Preview HTML remains soft-fail: broken-image feedback is useful to an interactive editor. Preview PDF is strict because it is a generated artifact, not interactive.
Migration
If you have templates with references to assets that have since been deleted, those
renders will now return errors instead of silently producing broken output. To identify
affected templates: render each template in a staging environment against production
data — any template that previously silently showed broken images will now return a
5xx with the missing asset filename in the error message.
Upgrade
Standard upgrade — no schema migrations, no new environment variables.
docker pull ghcr.io/OWNER/pulp-engine:v0.35.0