This is a submission for DEV's Summer Bug Smash: Clear the Lineup powered by Sentry.
Project Overview
HACKOPS is a local opportunity-production workspace. It keeps research, human approvals, tasks, generated artifacts, validation, and submission readiness together so a user can follow an opportunity from “GO” to a real delivery.
The portfolio view worked, but the execution workspace could disappear completely on a browser that supported the application's architecture while lacking two newer convenience APIs. A user could choose a project and arrive at an empty area with no stage, tasks, evidence, artifacts, or recovery controls.
Bug Fix or Performance Improvement
Two compatibility assumptions stopped the render pipeline:
- the shared HTML-escaping helper called
String.prototype.replaceAll; - the structured evidence renderer called
Object.hasOwn.
I reproduced the issue with an automated Chrome test that removes both APIs before any application JavaScript runs and then opens the real route:
/#execution/dev-summer-bug-smash
Before the fix, the test observed:
| Signal | Before |
|---|---|
| Workspace rendered | No |
| Stage badges | 0 |
| Workspace characters | 0 |
| Browser error | String(...).replaceAll is not a function |
The problem was not a missing feature. It was a broken navigation outcome in an existing codebase: after selecting a project, the user lost the whole execution context.
Code
The escaping helper now uses global regular expressions. They preserve the same ordered replacements without requiring replaceAll:
- .replaceAll('&', '&')
- .replaceAll('<', '<')
- .replaceAll('>', '>')
- .replaceAll('"', '"')
- .replaceAll("'", ''');
+ .replace(/&/g, '&')
+ .replace(/</g, '<')
+ .replace(/>/g, '>')
+ .replace(/\"/g, '"')
+ .replace(/'/g, ''');
The evidence renderer now uses one shared, long-supported prototype call instead of the newer static method:
+ const hasOwn = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
- Object.hasOwn(entry, 'key')
+ hasOwn(entry, 'key')
The label formatter received the same compatibility treatment:
- key.replaceAll('_', ' ')
+ key.replace(/_/g, ' ')
The regression test applies the compatibility profile before page code runs:
await page.addInitScript(() => {
Object.defineProperty(Object, 'hasOwn', {
value: undefined,
configurable: true,
writable: true,
});
Object.defineProperty(String.prototype, 'replaceAll', {
value: undefined,
configurable: true,
writable: true,
});
});
await page.goto(
`${baseUrl}/#execution/dev-summer-bug-smash`,
{ waitUntil: 'domcontentloaded' },
);
The complete patch and reproducible test are retained in the review package. The challenge accepts PRs or code snippets; this submission shows the exact code changes and does not depend on an upstream merge.
My Improvements
I kept the correction deliberately small:
- no polyfill bundle or compatibility dependency was added;
- the original escaping order remains unchanged;
- property ownership remains safe even if an object shadows
hasOwnProperty; - the regression test exercises the real application route and real project state;
- the same test captures full-page evidence before and after the patch.
Under the exact same simulated API profile, the result changed from a blank workspace to a usable execution view:
| Signal | Before | After |
|---|---|---|
| Workspace rendered | No | Yes |
| Stage badges | 0 | 1 |
| Workspace characters | 0 | 13,922 |
| Compatibility errors | 1 | 0 |
This does not claim support for Internet Explorer or browsers without ES modules. It closes a narrower, realistic gap: browsers modern enough for the application's architecture but older than Object.hasOwn or replaceAll.
The durable lesson was to test the user's navigation outcome, not only the helper functions. The regression assertion asks whether the selected execution workspace actually appears. That is the behavior a user depends on.



Top comments (0)