fixhunt

biome style/useConsistentObjectDefinitions

labelled safe
Runs / 2026-10-17T21-00-39-897Z-ymj0-biome-style_useConsistentObjectDefinitionsbiome 2.5.152026-10-17 21:00 UTC8 programs × 2 round(s)16 programs, 11 fired, 11 fixed, 0 findings, 2 rejectedmodel cost $0.0037

Analysis Nemotron 3 Super

The rule flags inconsistent usage of object literal property syntax by requiring either all properties to be written explicitly (`key: value`) or using shorthand notation (`key`) when the variable name matches the property key.

Fix: When the option 'syntax' is 'explicit', the autofix replaces shorthand property notation (e.g., `foo`) with its explicit equivalent (`foo: foo`) by duplicating the identifier as both the property key and value. When the option is 'shorthand', it replaces explicit notation where the key and value are identical identifiers (e.g., `foo: foo`) with the shorthand form (`foo`).

10 hazards
  • Rewriting `foo: foo` to `foo` in a `with` statement changes the object used for property lookup, potentially altering which properties are resolved due to differing object identity.
  • In `try/catch`, converting `{e: e}` to `{e}` may cause the catch clause's parameter `e` to shadow the property value incorrectly if the rewrite occurs inside the catch block, changing which variable is referenced.
  • Within a `for` loop's init or update clause, replacing `{i: i}` with `{i}` could affect timing if `i` has side effects (though unlikely for identifiers), but more critically, if `i` is declared with `var` in an outer scope, the shorthand may capture a different binding due to hoisting differences in evaluation context.
  • If the property value is a getter or setter (e.g., `get foo() {}`), rewriting to shorthand `foo` is invalid syntax and will cause a parse error, as shorthand does not support accessor properties.
  • When the object literal is used as the right-hand side of a comma operator (e.g., `let x = (y, {z: z});`), rewriting `{z: z}` to `{z}` does not change the value but may interfere with formatting tools that rely on explicit syntax for consistency, though semantically it remains equivalent.
  • In class fields, transforming `{method: method}` to `{method}` may break if `method` is not defined in the enclosing scope due to lexical scoping differences, though this is rare as class fields evaluate in the class scope.
  • If the identifier used in shorthand is later reassigned (e.g., `let f = 1; const o = {f}; f = 2;`), the object property retains the original value at the time of creation, which is preserved in the rewrite, so no hazard here—this is included to show that reassignment after object creation does not affect the equivalence.
  • Comments attached to the colon in explicit syntax (e.g., `foo: /* comment */ bar`) will be lost when rewriting to shorthand `foo`, as the autofix removes the colon and any surrounding whitespace/comments.
  • When the property key is an identifier but the value is a complex expression (e.g., `foo: bar + baz`), the rule does not fire, so no rewrite occurs—but if misapplied, rewriting such a case to shorthand would be a syntax error, highlighting that the fix only applies when key and value are the same identifier.
  • In non-strict mode, using `with` or `eval`, the rewritten shorthand may interact differently with scope chains if the object is used in a context where property resolution depends on the object's internal structure, though this is highly esoteric and unlikely.

Programs

idresulttitlehazard
r1-p001fix okCatch clause parameter shadowingIn try/catch, converting {e: e} to {e} may cause the catch clause's parameter e to shadow the property value incorrectly if the rewrite occurs inside the catch block, changing which variable is refere
r1-p002invalidWith statement object identityRewriting foo: foo to foo in a with statement changes the object used for property lookup, potentially altering which properties are resolved due to differing object identity.
r1-p003fix okNull/undefined distinction with optional chainingnull/undefined distinction, optional chaining short-circuit, nullish vs falsy
r1-p004silent prediction offOrder of evaluation with side effectsorder of evaluation when expressions are merged, duplicated or deleted (side effects run twice or never)
r1-p005silentClass field lexical scopingIn class fields, transforming {method: method} to {method} may break if method is not defined in the enclosing scope due to lexical scoping differences, though this is rare as class fields evaluate in
r1-p006fix okComments on colon lost in rewriteComments attached to the colon in explicit syntax (e.g., foo: /* comment */ bar) will be lost when rewriting to shorthand foo, as the autofix removes the colon and any surrounding whitespace/comments.
r1-p007fix okComments attached to removed/moved codecomments attached to the removed or moved code
r1-p008fix okArguments object and function lengtharguments object, function.length, default parameters, rest parameters
r2-p001fix okvar hoisting and re-declarationvar hoisting and re-declaration inside loops or after use
r2-p002fix okcomma operator RHSWhen the object literal is used as the right-hand side of a comma operator (e.g., `let x = (y, {z: z});`), rewriting `{z: z}` to `{z}` does not change the value but may interfere with formatting tools
r2-p003silentcomplex value expressionWhen the property key is an identifier but the value is a complex expression (e.g., `foo: bar + baz`), the rule does not fire, so no rewrite occurs—but if misapplied, rewriting such a case to shorthan
r2-p004invalidwith statement interactionIn non-strict mode, using `with` or `eval`, the rewritten shorthand may interact differently with scope chains if the object is used in a context where property resolution depends on the object's inte
r2-p005fix okstrict vs sloppy mode semanticsstrict vs sloppy mode semantics
r2-p006fix okreassignment after creationIf the identifier used in shorthand is later reassigned (e.g., `let f = 1; const o = {f}; f = 2;`), the object property retains the original value at the time of creation, which is preserved in the re
r2-p007fix oknull/undefined distinction with optional chainingnull/undefined distinction, optional chaining short-circuit, nullish vs falsy
r2-p008fix oksparse arrays and array-likessparse arrays, holes, Array(n) vs [n], array-likes

Sources

r1-p001 · Catch clause parameter shadowing
1function outer() {
2 var e = 'outer';
3 try {
4 throw new Error('test');
5 } catch (e) {
6 // Biome would rewrite {e: e} -> {e}
7 const obj = {e: e};
8 console.log(obj.e);
9 }
10 return e;
11}
12console.log(outer());
--- orig.js	2026-10-17 17:00:54.196133769 -0400
+++ fixed.js	2026-10-17 17:00:54.465137084 -0400
@@ -4,7 +4,7 @@
     throw new Error('test');
   } catch (e) {
     // Biome would rewrite {e: e} -> {e}
-    const obj = {e: e};
+    const obj = {e};
     console.log(obj.e);
   }
   return e;
Error: test
    at outer (<wd>/prog)
    at <wd>/prog
    at ModuleJob.run (node:internal/modules/esm/module_job:569:25)
    at async node:internal/modules/esm/loader:650:26
    at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:101:5)
outer
r1-p002 · With statement object identity (generated program does not parse: /home/sun/dev/diaghunt/runs/2026-10-17T21-00-3)
1var x = 1;
2var objA = {x: x};
3var objB = {x};
4with (objA) {
5 console.log(x); // logs 1 from objA.x
6}
7with (objB) {
8 console.log(x); // logs undefined because x not found (no property named 'x')
9}
r1-p003 · Null/undefined distinction with optional chaining
1let value = null;
2const obj = {value: value};
3// After fix: {value}
4console.log(obj.value ?? 'nullish');
5console.log((obj.value ?? 'nullish') === 'nullish');
6value = undefined;
7console.log(obj.value ?? 'nullish');
8console.log((obj.value ?? 'nullish') === 'nullish');
--- orig.js	2026-10-17 17:00:54.675139671 -0400
+++ fixed.js	2026-10-17 17:00:54.937142900 -0400
@@ -1,5 +1,5 @@
 let value = null;
-const obj = {value: value};
+const obj = {value};
 // After fix: {value}
 console.log(obj.value ?? 'nullish');
 console.log((obj.value ?? 'nullish') === 'nullish');
nullish
true
nullish
true
r1-p004 · Order of evaluation with side effects
1let count = 0;
2function side() {
3 return ++count;
4}
5const obj = {x: side(), y: side()};
6// If rewritten to {x, y} but only once evaluated? Not applicable.
7// Instead: duplicate eval in explicit form
8const obj2 = {a: side(), a: side()};
9console.log(count); // Should be 2 if both sides evaluated
10console.log(obj2.a); // Last wins: 2
4
4
r1-p005 · Class field lexical scoping
1class C {
2 method = () => 'hi';
3 static field = {
4 // Biome does not trigger here: method not same name as key
5 other: this.method
6 };
7}
8console.log(C.field.other());
r1-p006 · Comments on colon lost in rewrite
1let foo = 42;
2// Comment before
3const obj = {foo: /* important */ foo};
4// After fix: {foo} — comment lost
5console.log(obj.foo);
--- orig.js	2026-10-17 17:00:55.545150389 -0400
+++ fixed.js	2026-10-17 17:00:55.817153739 -0400
@@ -1,5 +1,5 @@
 let foo = 42;
 // Comment before
-const obj = {foo: /* important */ foo};
+const obj = {foo};
 // After fix: {foo} — comment lost
 console.log(obj.foo);
42
r1-p007 · Comments attached to removed/moved code
1let a = 1;
2// This comment is on the line with the shorthand candidate
3const obj = {/* keep me */ a: a, b: 2};
4// After fix: {/* keep me */ a, b: 2} — comment preserved? Autofix may keep it.
5// But if it deletes the whole prop, comment goes.
6// We test by having comment on the prop being removed.
7console.log(obj.a);
--- orig.js	2026-10-17 17:00:55.985155809 -0400
+++ fixed.js	2026-10-17 17:00:56.252159096 -0400
@@ -1,6 +1,6 @@
 let a = 1;
 // This comment is on the line with the shorthand candidate
-const obj = {/* keep me */ a: a, b: 2};
+const obj = {/* keep me */ a, b: 2};
 // After fix: {/* keep me */ a, b: 2} — comment preserved? Autofix may keep it.
 // But if it deletes the whole prop, comment goes.
 // We test by having comment on the prop being removed.
1
r1-p008 · Arguments object and function length
1function f(a, b) {
2 // Biome would rewrite {a: a, b: b} -> {a, b}
3 const obj = {a: a, b: b};
4 console.log(obj.a + ', ' + obj.b);
5 console.log(arguments.length);
6}
7f(10, 20);
--- orig.js	2026-10-17 17:00:56.419161152 -0400
+++ fixed.js	2026-10-17 17:00:56.691164501 -0400
@@ -1,6 +1,6 @@
 function f(a, b) {
   // Biome would rewrite {a: a, b: b} -> {a, b}
-  const obj = {a: a, b: b};
+  const obj = {a, b};
   console.log(obj.a + ', ' + obj.b);
   console.log(arguments.length);
 }
10, 20
2
r2-p001 · var hoisting and re-declaration
1for (var i = 0; i < 2; i++) {
2 var j = i;
3 var k = {j: j};
4}
5console.log(typeof k === 'object' && k !== null ? k.j : 'null');
--- orig.js	2026-10-17 17:01:03.008242154 -0400
+++ fixed.js	2026-10-17 17:01:03.285245553 -0400
@@ -1,5 +1,5 @@
 for (var i = 0; i < 2; i++) {
   var j = i;
-  var k = {j: j};
+  var k = {j};
 }
 console.log(typeof k === 'object' && k !== null ? k.j : 'null');
1
r2-p002 · comma operator RHS
1let y = 0;
2let x = (y++, {z: z});
3function z() { return 42; }
4console.log(typeof x === 'object' && x !== null && typeof x.z === 'function' ? x.z() : -1);
--- orig.js	2026-10-17 17:01:03.456247652 -0400
+++ fixed.js	2026-10-17 17:01:03.734251064 -0400
@@ -1,4 +1,4 @@
 let y = 0;
-let x = (y++, {z: z});
+let x = (y++, {z});
 function z() { return 42; }
 console.log(typeof x === 'object' && x !== null && typeof x.z === 'function' ? x.z() : -1);
42
r2-p003 · complex value expression
1let foo = 1;
2let bar = 2;
3let baz = 3;
4let obj = {foo: bar + baz};
5console.log(obj.foo);
5
r2-p004 · with statement interaction (generated program does not parse: /home/sun/dev/diaghunt/runs/2026-10-17T21-00-3)
1(function() {
2 'use sloppy';
3 let obj = {prop: prop};
4 let prop = 99;
5 with (obj) {
6 console.log(prop);
7 }
8})();
r2-p005 · strict vs sloppy mode semantics
1'use strict';
2let a = 1;
3let obj = {a: a};
4console.log(obj.a);
5'use sloppy';
6let b = 2;
7let obj2 = {b: b};
8console.log(obj2.b);
--- orig.js	2026-10-17 17:01:04.181256548 -0400
+++ fixed.js	2026-10-17 17:01:04.461259983 -0400
@@ -1,8 +1,8 @@
 'use strict';
 let a = 1;
-let obj = {a: a};
+let obj = {a};
 console.log(obj.a);
 'use sloppy';
 let b = 2;
-let obj2 = {b: b};
+let obj2 = {b};
 console.log(obj2.b);
1
2
r2-p006 · reassignment after creation
1let f = 1;
2const o = {f: f};
3f = 2;
4console.log(o.f);
--- orig.js	2026-10-17 17:01:04.629262044 -0400
+++ fixed.js	2026-10-17 17:01:04.903265405 -0400
@@ -1,4 +1,4 @@
 let f = 1;
-const o = {f: f};
+const o = {f};
 f = 2;
 console.log(o.f);
1
r2-p007 · null/undefined distinction with optional chaining
1let maybe = undefined;
2let obj = {maybe: maybe};
3console.log(obj.maybe ?? 'default');
4try {
5 console.log(obj.nonexistent?.prop);
6} catch (e) {
7 console.log('caught:', e.name);
8}
--- orig.js	2026-10-17 17:01:05.086267649 -0400
+++ fixed.js	2026-10-17 17:01:05.353270923 -0400
@@ -1,5 +1,5 @@
 let maybe = undefined;
-let obj = {maybe: maybe};
+let obj = {maybe};
 console.log(obj.maybe ?? 'default');
 try {
   console.log(obj.nonexistent?.prop);
default
undefined
r2-p008 · sparse arrays and array-likes
1let arr = new Array(3);
2arr[1] = 'present';
3let obj = {arr: arr};
4console.log('length:', obj.arr.length);
5console.log('0 in obj.arr:', 0 in obj.arr);
6console.log('1 in obj.arr:', 1 in obj.arr);
7console.log('2 in obj.arr:', 2 in obj.arr);
--- orig.js	2026-10-17 17:01:05.517272933 -0400
+++ fixed.js	2026-10-17 17:01:05.782276183 -0400
@@ -1,6 +1,6 @@
 let arr = new Array(3);
 arr[1] = 'present';
-let obj = {arr: arr};
+let obj = {arr};
 console.log('length:', obj.arr.length);
 console.log('0 in obj.arr:', 0 in obj.arr);
 console.log('1 in obj.arr:', 1 in obj.arr);
length: 3
0 in obj.arr: false
1 in obj.arr: true
2 in obj.arr: false