Repository navigation
v5.3.3
Transactions and replication
- A write that reached the transaction log always commits. rocksdb-js writes an audited transaction's log entry during the first native commit, before it checks for conflicts. Before, Harper could give up on a commit that conflicted after that point: on its retry cap, its conflict budget, a lapsed record-lock lease, or a closing database. The log then held a write the database never applied. Such a commit now retries until it lands, as replication-applied writes already do, and keeps its record locks until then. (#3266)
- Replicated duplicate retries no longer walk audit history. Sometimes a replicated write had already committed while its first attempt hit a conflict. Its retry then searched audit history even though the stored record showed the write had already landed. Receivers could stall on old audit entries or apply an increment twice. The retry now recognizes a write that has already landed before it reads the audit log. (#3366)
Startup and configuration
- Tables without a primary key no longer block startup. On upgrade to 5.2 or 5.3, a catalog row that lost its
isPrimaryKeyflag stopped Harper from starting ("The system database failed to load"). If the app schema declared a primary key on such a table, the whole schema failed to load, healthy tables included. Both cases now load, as they did on 5.1. (#3244) - Malformed configuration YAML is rejected. A root config with YAML parse errors or duplicate keys could be adopted without warning. Harper now rejects it before any thread uses it, and the error reports the code and location without echoing the file's contents. (#2986)
MQTT
- Last wills are published for non-super users. Before, the server read the will's
system.hdb_session_willrow as the client, so only super users ever had a will published. Other users' wills were dropped, their rows leaked, and each disconnect loggedError publishing MQTT will. The will's publish is now authorized like the client's other publishes, and the server manages the row itself. (#3302) - MQTT v5 reports a missing login as Not authorized (0x87). When
mqtt.requireAuthenticationis off, an anonymous client's SUBSCRIBE or PUBLISH to a protected topic now fails with0x87instead of0x80("Unspecified error"). A delivery that races a disconnect now logs the topic it was for. (#3303)
REST, HTTP and components
- Nested
selectno longer returns 500 on missing relationships. A nested selection now keeps a missing relationship target, and projects ordinary JSON values instead of failing the request. (#3171) - Gzip from Node middleware is no longer corrupt on Node 26.11+. A new pipe fast path in Node 26.11 bypassed the
compressionmiddleware's patchedres.writeinsidewithNodeAdapterresponses, which corrupted gzip responses. Piped chunks now go throughwrite().install_node_modulesalso parses npm's JSON report, so it returns the same object on every npm version, including 11.20. (#3108) package_componentno longer packs the Harper install once per plugin. Whennode_moduleswas included, it followed each sub-component'snode_modules/harperlink and packed the whole running install every time. That made every clone of an app with a plugin much larger and slower. Those links are now left out, and the size estimate still matches what is packed. (#3216)
Analytics
- Aggregates no longer store
NaNfor measures missing from some samples. A measure that a metric's first sample lacked was stored asNaN, or dropped for per-thread metrics. Each measure is now folded over only the samples that carry it, which also corrects a mean that had counted samples without the measure. Measures present in every sample aggregate exactly as before. (#3139)
Also in this release
New tests confirming that a backup purge waits for create_backup to publish its backup (#3319, #3378), plus design-note updates.
Full changelog: v5.3.2...v5.3.3