# biome suspicious/noPrototypeBuiltins: fix changes program behavior

Internal evidence sheet generated by fixhunt. Not an issue text. A human re-verifies, checks the duplicates
below, and writes the upstream report in their own words following the project's AI policy.

- Tool: biome 2.5.15
- Rule: suspicious/noPrototypeBuiltins (tool labels the fix: safe, this fix reported as safe)
- Oracle: fix-changes-behavior
- Judge (Nemotron 3 Ultra, advisory): intended-change, severity low. The rule rewrites foo.hasOwnProperty('x') to Object.hasOwn(foo, 'x') specifically to bypass any shadowed or missing hasOwnProperty on the receiver. The original code throws a TypeError when accessing the property on undefined; the rewritten code throws a different TypeError when Object.hasOwn receives undefined. Both fail as expected for an undefined receiver, and the change in error message reflects the intended semantic shift from a prototype method call to a static method call.
- Program: minimized from 8 to 8 lines

## Reproducer

```js
if (typeof foo === 'undefined') {
  try {
    console.log(foo.hasOwnProperty('x'));
  } catch (e) {
    console.log(e.name, e.message);
  }
}
var foo = { x: 1 };
```

## Commands

```sh
node prog.js
bunx @biomejs/biome lint --only=suspicious/noPrototypeBuiltins --write prog.js
node prog.js
```

## Observed

```
stdout before:
TypeError Cannot read properties of undefined (reading 'hasOwnProperty')
stdout after:
TypeError Cannot convert undefined or null to object
```

## Diff applied by the fix

```diff
--- orig.js	2026-10-22 13:36:23.487989364 -0400
+++ fixed.js	2026-10-22 13:36:26.081033160 -0400
@@ -1,6 +1,6 @@
 if (typeof foo === 'undefined') {
   try {
-    console.log(foo.hasOwnProperty('x'));
+    console.log(Object.hasOwn(foo, 'x'));
   } catch (e) {
     console.log(e.name, e.message);
   }
```

## Why the rewrite is not equivalent (model draft, verify before use)

The original code checks `typeof foo === 'undefined'`; since `foo` is later defined as `{x:1}`, this condition is false, so the block is skipped—no error occurs. However, due to hoisting, `var foo` is initialized to `undefined` at runtime *before* assignment, making `typeof foo === 'undefined'` true when evaluated early in execution order. Inside the block, `foo.hasOwnProperty('x')` attempts to call a method on `undefined`, throwing a TypeError with message "Cannot read properties of undefined". The replacement uses `Object.hasOwn(foo, 'x')`, which requires its first argument to be an object; passing `undefined` causes it to throw immediately with "Cannot convert undefined or null to object"—a different error message, proving the behavior changed despite identical control flow logic. The fix assumes `foo` is always an object, ignoring the hoisted `undefined` state that triggers the exception path. This alters observable output, violating semantic equivalence.

## Upstream search

Queries: "noPrototypeBuiltins fix", "suspicious noPrototypeBuiltins hasOwnProperty call", "Object.hasOwn replacement for prototype method", "fix behavior change in typeof guard block"

- related: https://github.com/biomejs/biome/issues/10769
  same noPrototypeBuiltins rule but different construct (computed member expression with __proto__) and different unsafe fix
- related: https://github.com/biomejs/biome/issues/7900
  same noPrototypeBuiltins rule mentioned in crash report but different defect (crash vs behavior change)
- related: https://github.com/biomejs/biome/issues/281
  same noPrototypeBuiltins rule mentioned in config but different defect (false positive on unused variables)
- related: https://github.com/biomejs/biome/issues/4121
  same noPrototypeBuiltins rule mentioned in config but different defect (line width for template literals)

<details><summary>All hits</summary>

- [github, open] 💅 `useSortedProperties` can produce invalid CSS when the final semicolon is omitted — https://github.com/biomejs/biome/issues/12417
- [github, open] 💅 `useSortedProperties` moves Sass variable declarations below their uses — https://github.com/biomejs/biome/issues/12414
- [github, open] 💅 `useSortedProperties` can change behavior when reordering nested CSS rules — https://github.com/biomejs/biome/issues/12413
- [github, open] 💅 `noUnnecessaryConditions`: false positive on an overloaded call with `undefined` as the default argument (Vue `inject`) — https://github.com/biomejs/biome/issues/12040
- [github, open] 💅 `noSkippedTests` conditionally skip fix suggestion — https://github.com/biomejs/biome/issues/9295
- [github, open] 💅 Actually used private method considered unused — https://github.com/biomejs/biome/issues/8185
- [github, open] 💅 cannot detect that the StrictMode component of React is being exported. — https://github.com/biomejs/biome/issues/10609
- [github, open] 💅 noUnnecessaryConditions callback overload false positive — https://github.com/biomejs/biome/issues/11439
- [github, open] 💅 lint/a11y/useAnchorContent: the PascalCase component allowance is applied only to self-closing elements — https://github.com/biomejs/biome/issues/11872
- [github, open] 💅 useLiteralKeys flags `__proto__` in a computed member expression and offers an unsafe fix that conflicts with noProto — https://github.com/biomejs/biome/issues/10769
- [tavily] 📝 Biome is crashing when opening a .ejs file · Issue #7900 · biomejs/biome · GitHub — https://github.com/biomejs/biome/issues/7900
- [tavily] 🐛 noUnusedVariables false positive · Issue #281 · biomejs/biome · GitHub — https://github.com/biomejs/biome/issues/281
- [tavily] 📝 Line width is not respected for functions that return template literals · Issue #4121 · biomejs/biome · GitHub — https://github.com/biomejs/biome/issues/4121
- [tavily] fix(lint/useExhaustiveDependencies): correct fix for method calls by siketyan · Pull Request #7709 · biomejs/biome · GitHub — https://github.com/biomejs/biome/pull/7709
- [tavily] fix(css_parser): fix is at unicode range check by xin2017338 · Pull Request #3745 · biomejs/biome · GitHub — https://github.com/biomejs/biome/pull/3745
- [tavily] fix(linter): fix aliased paths in `useImportExtensions` by arendjr · Pull Request #7597 · biomejs/biome · GitHub — https://github.com/biomejs/biome/pull/7597
- [tavily] fix(useConsistentTestIt): fix panic when applying code fix by dyc3 · Pull Request #9942 · biomejs/biome · GitHub — https://github.com/biomejs/biome/pull/9942
- [github, closed] 💅 `noThisInStatic` safe fix is not safe — https://github.com/biomejs/biome/issues/10011

</details>
