Skip to content

Code Quality: PR #376 #1032

Code Quality: PR #376

Code Quality: PR #376 #1032

Triggered via dynamic April 28, 2026 21:47
Status Success
Total duration 2m 9s
Artifacts

codeql

on: dynamic
Matrix: analyze
Fit to window
Zoom out
Zoom in

Annotations

5 warnings
Race condition clears loadPromise before unlink completes, allowing duplicate xcrun invocations: src/utils/device-name-resolver.ts#L68
In refreshDeviceNames, the IIFE sets `loadPromise = null` in the finally block before awaiting `unlink(tmpFile)`. Because the assignment happens synchronously at the start of the finally, a concurrent caller invoking refreshDeviceNames during the unlink await will see loadPromise as null and a fresh cache, but if the cache check fails for any reason (e.g., the catch branch did not populate it on a TTL boundary), a second xcrun process can be spawned while the first is still cleaning up. More importantly, the deduplication guarantee is weaker than intended — `loadPromise` should remain set for the entire lifetime of the returned promise so awaiters all observe the same in-flight work.
Race condition: loadPromise cleared before unlink completes allows concurrent refreshes to collide: src/utils/device-name-resolver.ts#L70
Inside the IIFE's finally block, `loadPromise = null` is set before `await unlink(tmpFile)` runs. Because the tmpFile path includes `Date.now()`, this is mostly safe, but more importantly: setting `loadPromise = null` inside the async finally means any caller that awaits `refreshDeviceNames()` returns before unlink finishes, and a subsequent call entering while unlink is still pending will start a second xcrun invocation rather than dedup. This undermines the stated 'in-flight deduplication' goal and can spawn overlapping subprocesses under load.
Fire-and-forget refresh via `void refreshDeviceNames()` may surface unhandled promise rejections: src/utils/device-name-resolver.ts#L84
`ensureDeviceNamesRefresh` discards the returned promise with `void`. While `refreshDeviceNames` catches errors from execFile/readFile internally, any unexpected synchronous throw or future code change inside the IIFE that escapes the try/catch would become an unhandled rejection, which Node may treat as fatal in newer versions. Since `resolveDeviceName` is called from rendering/pipeline code, an unhandled rejection here could crash the process.
Analyze (python)
Starting April 2026, the CodeQL Action will skip computing file coverage information on pull requests to improve analysis performance. File coverage information will still be computed on non-PR analyses. To opt out of this change, create a custom repository property with the name `github-codeql-file-coverage-on-prs` and the type "True/false", then set this property to `true` in the repository's settings.
Analyze (javascript-typescript)
Starting April 2026, the CodeQL Action will skip computing file coverage information on pull requests to improve analysis performance. File coverage information will still be computed on non-PR analyses. To opt out of this change, create a custom repository property with the name `github-codeql-file-coverage-on-prs` and the type "True/false", then set this property to `true` in the repository's settings.