The probe was deliberate. Pick a known unsafe input — a long sequence of /a/a/a/... path segments — pass it to the API helper, and see what happens. The behavior we expected was a 404 from the server and a clean error report from the client. The system already had defenses against path traversal, against percent-encoded variants, against control characters. Long-but-otherwise-normal paths are uninteresting from a security perspective.

The behavior we got was approximately what we expected. Merus returned 404. The client formatted an error and exited. What surprised us was the error itself: HTTP 404 Not Found — /a/a/a/a/a/a/a/a/... for four thousand characters of stderr output. The error message dumped the whole endpoint verbatim because the formatter just template-stringed ${cleanEndpoint} into the output.

For a normal endpoint — say /tasks/index — that's fine. Twelve characters in the message. For a pathologically long endpoint, the message itself becomes the noise. An attorney whose tool was reporting that error in their terminal would see four thousand characters of slashes-and-letters before they got to the explanatory text. The actionable information (this endpoint doesn't exist) is buried.

The fix

One line. Before formatting, check the endpoint length. If it's over 120 characters, replace the message with the first 100 characters, an ellipsis, and the total character count. The full endpoint is still in the audit log entry — the trim is cosmetic, for the stderr message only.

Verified two cases. A 4000-character endpoint now shows HTTP 404 Not Found — /a/a/a/.../a/a/...(4000 chars) followed by the explanation. A normal 20-character endpoint shows exactly the same message as before. Behavior change for the pathological case, no change for the normal case.

The habit

The interesting part isn't the fix. It's what the probe found that wasn't a security bug, wasn't a correctness bug, but was a usability bug that would have been invisible until an attorney hit it for the first time. Most defensive-code reviews focus on what comes IN to a function — what if the input is malformed, malicious, oversized, encoded, decoded twice. That's a habit worth keeping. But this probe surfaced an output that the function generated faithfully and the human couldn't read.

Defensive output is a smaller discipline than defensive input, but it's the same kind of habit. Code that produces messages for humans should consider what happens when the data being interpolated is itself pathological. A filename that's a thousand characters long. A description field with embedded newlines. A user-supplied note with ANSI escape sequences. These don't break the program; they break the human's ability to read what the program said.

The list of places where this matters is approximately every console.error(template) call site. We're not going to audit them all this week. But the next time we add one, we'll think about what happens when the templated value is larger or stranger than the message was designed for, and we'll cap it at a sensible length.

The version on the install URL is 4.5.73. Small release. The work continues at the pace of one verified release at a time, and the system is now defensive about the noise it produces, not just the noise it consumes.