Skip to content

fix(eslint): gate replaceWithGetErrorMessage suggestion on hasResolvableLocalBinding in no-err-stack-then-string-fallback - #49501

Merged
pelikhan merged 5 commits into
mainfrom
copilot/fix-no-err-stack-then-string-fallback
Aug 1, 2026
Merged

fix(eslint): gate replaceWithGetErrorMessage suggestion on hasResolvableLocalBinding in no-err-stack-then-string-fallback#49501
pelikhan merged 5 commits into
mainfrom
copilot/fix-no-err-stack-then-string-fallback

Conversation

Copilot AI commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

no-err-stack-then-string-fallback unconditionally offered a replaceWithGetErrorMessage autofix suggestion regardless of whether getErrorMessage was imported in the file. Accepting the suggestion in a file without the import (e.g. copilot_sdk_driver.cjs) would silently replace the last-resort error handler with getErrorMessage(err), throwing ReferenceError at runtime. Three sibling rules already guard against this with hasResolvableLocalBinding.

Changes

  • no-err-stack-then-string-fallback.ts: Add isDefinitionAvailableAtNode + hasResolvableLocalBinding (identical pattern to no-json-stringify-error, prefer-get-error-message-over-string, no-caught-error-interpolation). The suggest array is now [] when getErrorMessage is not in scope; diagnostic still fires unconditionally.

  • no-err-stack-then-string-fallback.test.ts:

    • Updated existing invalid test cases to include const { getErrorMessage } = require("./error_helpers.cjs") so suggestion coverage is preserved.
    • Added new test case asserting suggestions: [] when getErrorMessage is not in scope, including the exact copilot_sdk_driver.cjs pattern from the issue.
// Before: suggestion offered regardless of imports — applying it breaks this file
process.stderr.write(`[copilot-sdk-driver] unhandled error: ${err instanceof Error ? err.stack : String(err)}\n`);
//                                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// diagnostic: preferGetErrorMessage  |  suggestions: [replaceWithGetErrorMessage]  ← unsafe, no import

// After: diagnostic still fires, but suggestions: [] — no unsafe autofix offered

Copilot AI and others added 2 commits August 1, 2026 07:01
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
…-string-fallback rule

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

PR Triage

  • Category: bug | Risk: low | Priority: low
  • Score: 18/100 (impact 10 + urgency 5 + quality 3)
  • Recommended action: defer
  • Batch: wip-drafts

Note: Draft, only lock.yml regenerated so far

Generated by 🔧 PR Triage Agent · auto · 48.9 AIC · ⌖ 6.24 AIC · ⊞ 7.9K ·

Copilot AI changed the title [WIP] Fix no-err-stack-then-string-fallback rule to check for getErrorMessage import fix(eslint): gate replaceWithGetErrorMessage suggestion on hasResolvableLocalBinding in no-err-stack-then-string-fallback Aug 1, 2026
Copilot AI requested a review from pelikhan August 1, 2026 07:11
@pelikhan
pelikhan marked this pull request as ready for review August 1, 2026 07:20
Copilot AI review requested due to automatic review settings August 1, 2026 07:20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Gates an ESLint autofix on a resolvable getErrorMessage binding to prevent runtime failures.

Changes:

  • Adds scope-aware suggestion gating.
  • Adds binding/no-binding tests.
  • Regenerates an unrelated workflow lock file.
Show a summary per file
File Description
no-err-stack-then-string-fallback.ts Adds binding resolution logic.
no-err-stack-then-string-fallback.test.ts Tests suggestion availability.
daily-byok-ollama-test.lock.yml Changes generated model-routing configuration.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Suppressed comments (1)

eslint-factory/src/rules/no-err-stack-then-string-fallback.ts:82

  • When the current scope contains a later same-name lexical declaration, this loop skips its unavailable definition and continues to an outer getErrorMessage. The inner declaration still shadows the outer binding throughout the block, so the suggested call would hit the inner binding's temporal dead zone and throw. Stop at the first scope that defines the name and return whether that definition is available; add a nested-shadow regression case.
        const variable = scope.set.get(name);
        if (variable && variable.defs.some(def => isDefinitionAvailableAtNode(def, node))) {
  • Files reviewed: 3/3 changed files
  • Comments generated: 2
  • Review effort level: Balanced

Comment on lines +50 to +52
const definitionNode = definition.name ?? definition.node;
if (!definitionNode?.range || !node.range) return false;
return definitionNode.range[0] < node.range[0];
(umask 177 && touch /tmp/gh-aw/threat-detection/detection.log)
GH_AW_MAX_AI_CREDITS="${{ vars.GH_AW_DEFAULT_DETECTION_MAX_AI_CREDITS || '400' }}"
printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.43/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"raw.githubusercontent.com\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"targets\":{\"copilot\":{\"host\":\"host.docker.internal:11434\"}}},\"container\":{\"imageTag\":\"0.27.43,squid=sha256:26be5e0b8c8f4c41c8a59126b29bb5d80b07253597472ded2a16bdd75abcbf9d,agent=sha256:04e2d1987a565000a8f114b89d806ae7a3864dd4f944be65275b28c93d8690e6,api-proxy=sha256:d85f57975af5ea23af4996e41ed73fbc8f5b4a47402472bfe82e508f352cb0c1,cli-proxy=sha256:65c45ea2967984d0024f3df61bc71335658a77ede96c8d9665da7a5f33a795ab\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
printf '%s\n' "{\"\$schema\":\"https://github.com/github/gh-aw-firewall/releases/download/v0.27.43/awf-config.schema.json\",\"network\":{\"allowDomains\":[\"api.business.githubcopilot.com\",\"api.enterprise.githubcopilot.com\",\"api.github.com\",\"api.githubcopilot.com\",\"api.individual.githubcopilot.com\",\"github.com\",\"host.docker.internal\",\"raw.githubusercontent.com\",\"registry.npmjs.org\",\"telemetry.enterprise.githubcopilot.com\"]},\"apiProxy\":{\"enabled\":true,\"enableTokenSteering\":true,\"maxRuns\":500,\"maxAiCredits\":${GH_AW_MAX_AI_CREDITS},\"maxCacheMisses\":5,\"defaultAiCreditsPricing\":{\"input\":0.000001,\"output\":0.000001},\"targets\":{\"copilot\":{\"host\":\"host.docker.internal:11434\"}},\"models\":{\"agent\":[\"sonnet-6x\",\"gpt-5.4\",\"gpt-5.5\",\"gpt-5.6\",\"gpt-5.3\",\"gemini-pro\",\"any\"],\"antigravity\":[\"copilot/antigravity*\",\"google/antigravity*\",\"gemini/antigravity*\"],\"any\":[\"copilot/*\",\"anthropic/*\",\"openai/*\",\"google/*\",\"gemini/*\"],\"auto\":[\"copilot/auto\",\"large\"],\"claude\":[\"agent\"],\"codex\":[\"agent\"],\"coding\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\",\"gpt-5-codex\",\"kimi\"],\"computer-use\":[\"copilot/*computer-use*\",\"google/*computer-use*\",\"gemini/*computer-use*\",\"openai/*computer-use*\"],\"copilot\":[\"agent\"],\"deep-research\":[\"copilot/deep-research*\",\"copilot/o3-deep-research*\",\"copilot/o4-mini-deep-research*\",\"google/deep-research*\",\"gemini/deep-research*\",\"openai/o3-deep-research*\",\"openai/o4-mini-deep-research*\"],\"fable\":[\"copilot/*fable*\",\"anthropic/*fable*\"],\"gemini\":[\"agent\"],\"gemini-3-flash\":[\"copilot/gemini-3*flash*\",\"google/gemini-3*flash*\",\"gemini/gemini-3*flash*\"],\"gemini-3-pro\":[\"copilot/gemini-3*pro*\",\"google/gemini-3*pro*\",\"google/nano-banana*\",\"gemini/gemini-3*pro*\"],\"gemini-3.1-flash\":[\"copilot/gemini-3.1*flash*\",\"google/gemini-3.1*flash*\",\"gemini/gemini-3.1*flash*\"],\"gemini-3.1-pro\":[\"copilot/gemini-3.1*pro*\",\"google/gemini-3.1*pro*\",\"gemini/gemini-3.1*pro*\"],\"gemini-3.5-flash\":[\"copilot/gemini-3.5*flash*\",\"google/gemini-3.5*flash*\",\"gemini/gemini-3.5*flash*\"],\"gemini-3.6-flash\":[\"copilot/gemini-3.6*flash*\",\"google/gemini-3.6*flash*\",\"gemini/gemini-3.6*flash*\"],\"gemini-flash\":[\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"],\"gemini-flash-lite\":[\"copilot/gemini-*flash*lite*\",\"google/gemini-*flash*lite*\",\"gemini/gemini-*flash*lite*\"],\"gemini-omni\":[\"copilot/gemini-omni*\",\"google/gemini-omni*\",\"gemini/gemini-omni*\"],\"gemini-pro\":[\"copilot/gemini-*pro*\",\"google/gemini-*pro*\",\"gemini/gemini-*pro*\"],\"gemma\":[\"copilot/gemma*\",\"google/gemma*\",\"gemini/gemma*\"],\"gpt-5\":[\"copilot/gpt-5*\",\"openai/gpt-5*\"],\"gpt-5-codex\":[\"copilot/gpt-5*codex*\",\"openai/gpt-5*codex*\"],\"gpt-5-mini\":[\"copilot/gpt-5*mini*\",\"openai/gpt-5*mini*\"],\"gpt-5-nano\":[\"copilot/gpt-5*nano*\",\"openai/gpt-5*nano*\"],\"gpt-5-pro\":[\"copilot/gpt-5*pro*\",\"openai/gpt-5*pro*\"],\"gpt-5.1\":[\"copilot/gpt-5.1*\",\"openai/gpt-5.1*\"],\"gpt-5.2\":[\"copilot/gpt-5.2*\",\"openai/gpt-5.2*\"],\"gpt-5.3\":[\"copilot/gpt-5.3*\",\"openai/gpt-5.3*\"],\"gpt-5.4\":[\"copilot/gpt-5.4*\",\"openai/gpt-5.4*\"],\"gpt-5.5\":[\"copilot/gpt-5.5*\",\"openai/gpt-5.5*\"],\"gpt-5.6\":[\"copilot/gpt-5.6*\",\"openai/gpt-5.6*\"],\"grok\":[\"copilot/*grok*\",\"openai/*grok*\"],\"haiku\":[\"copilot/*haiku*\",\"anthropic/*haiku*\"],\"image-generation\":[\"copilot/gpt-image*\",\"openai/gpt-image*\",\"openai/chatgpt-image*\",\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"google/imagen*\"],\"kimi\":[\"copilot/kimi*\",\"openai/kimi*\"],\"kiwi\":[\"copilot/kiwi*\",\"openai/kiwi*\"],\"large\":[\"sonnet\",\"gpt-5-pro\",\"gpt-5\",\"gemini-pro\"],\"lyria\":[\"google/lyria*\",\"gemini/lyria*\",\"copilot/lyria*\"],\"mai-code\":[\"copilot/MAI-Code*\",\"copilot/mai-code*\",\"openai/MAI-Code*\"],\"mai-code-1-flash-picker\":[\"copilot/MAI-Code-1-Flash-picker*\",\"copilot/mai-code-1-flash-picker*\",\"openai/MAI-Code-1-Flash-picker*\"],\"mini\":[\"haiku\",\"gpt-5-mini\",\"gpt-5-nano\",\"gemini-flash-lite\"],\"nano-banana\":[\"copilot/nano-banana*\",\"google/nano-banana*\",\"gemini/nano-banana*\"],\"opus\":[\"copilot/*opus*\",\"anthropic/*opus*\"],\"opusplan\":[\"opus?effort=high\"],\"raptor-mini\":[\"copilot/raptor*\",\"openai/raptor*\"],\"reasoning\":[\"copilot/o1*\",\"copilot/o3*\",\"copilot/o4*\",\"openai/o1*\",\"openai/o3*\",\"openai/o4*\"],\"robotics\":[\"copilot/*robotics*\",\"google/*robotics*\",\"gemini/*robotics*\"],\"small\":[\"mini\"],\"small-agent\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash\"],\"sonnet\":[\"copilot/*sonnet*\",\"anthropic/*sonnet*\"],\"sonnet-6x\":[\"copilot/*sonnet-4.5*\",\"copilot/*sonnet-4.6*\",\"copilot/*sonnet-5*\",\"copilot/*sonnet-4-5-*\",\"anthropic/*sonnet-4-5-*\",\"copilot/*sonnet-4-6*\",\"anthropic/*sonnet-4-6*\",\"anthropic/*sonnet-5*\"],\"summarization\":[\"haiku\",\"gpt-5-mini\",\"gemini-flash-lite\",\"mini\"],\"veo\":[\"google/veo*\",\"gemini/veo*\"],\"vision\":[\"copilot/gemini-*image*\",\"google/gemini-*image*\",\"gemini/gemini-*image*\",\"copilot/gemini-*flash*\",\"google/gemini-*flash*\",\"gemini/gemini-*flash*\"]}},\"container\":{\"imageTag\":\"0.27.43,squid=sha256:26be5e0b8c8f4c41c8a59126b29bb5d80b07253597472ded2a16bdd75abcbf9d,agent=sha256:04e2d1987a565000a8f114b89d806ae7a3864dd4f944be65275b28c93d8690e6,api-proxy=sha256:d85f57975af5ea23af4996e41ed73fbc8f5b4a47402472bfe82e508f352cb0c1,cli-proxy=sha256:65c45ea2967984d0024f3df61bc71335658a77ede96c8d9665da7a5f33a795ab\"},\"logging\":{\"proxyLogsDir\":\"/tmp/gh-aw/sandbox/firewall/logs\",\"auditDir\":\"/tmp/gh-aw/sandbox/firewall/audit\"}}" > "${RUNNER_TEMP}/gh-aw/awf-config.json"
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check.

No ADR enforcement needed: PR #49501 does not have the 'implementation' label and has 0 new lines of code in business logic directories (threshold: 100).

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

⚠️ PR Code Quality Reviewer failed during code quality review.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skills-Based Review 🧠

Applied /diagnosing-bugs and /tdd — no blocking issues; one gap worth addressing.

📋 Key Themes & Highlights

Key Themes

  • Root cause well addressed: gating the suggestion on hasResolvableLocalBinding matches the pattern already used in three sibling rules — consistent and correct.
  • Regression test added: the new suggestions: [] case covering copilot_sdk_driver.cjs directly proves the fix.
  • ESM branch untested: isDefinitionAvailableAtNode returns early for ImportBinding without a test — see inline comment.

Positive Highlights

  • ✅ Identical guard pattern to sibling rules — easy to audit and maintain
  • ✅ Existing tests updated to include the import so suggestion coverage is preserved
  • ✅ Diagnostic still fires unconditionally; only the unsafe autofix is suppressed

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · sonnet46 · 24.5 AIC · ⌖ 12.5 AIC · ⊞ 7K
Comment /matt to run again

],
});
});
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/tdd] Tests only cover the CJS require path — the ESM ImportBinding branch of isDefinitionAvailableAtNode is untested.

isDefinitionAvailableAtNode returns true immediately for ImportBinding, so the suggestion will fire for ESM imports too. Adding one test case with import { getErrorMessage } from '...' would confirm that branch and prevent a silent regression if the early-return is removed.

💡 Suggested test snippet
{
  code: `import { getErrorMessage } from './error_helpers.cjs'; const msg = err instanceof Error ? err.stack : String(err);`,
  errors: [{
    messageId: 'preferGetErrorMessage',
    data: { errorVar: 'err' },
    suggestions: [{ messageId: 'replaceWithGetErrorMessage', data: { errorVar: 'err' }, output: `import { getErrorMessage } from './error_helpers.cjs'; const msg = getErrorMessage(err);` }],
  }],
}

Use an ESM rule tester instance with { parserOptions: { sourceType: 'module' } }.

@copilot please address this.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: no-err-stack-then-string-fallback ESLint rule fix

The core logic — gating the replaceWithGetErrorMessage suggestion on hasResolvableLocalBinding — is a sound correctness fix. Tests are comprehensive.

Two prior comments flag issues:

  1. Self-referential binding edge case (line 52): the range check may consider a const getErrorMessage = ... binding available during its own initializer — a narrow but real edge case.
  2. Lock file churn: the generated lock file includes a large unrelated model-routing policy update alongside the ESLint fix.

Overall the change is correct and non-blocking.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · sonnet46 · 21.6 AIC · ⌖ 9.79 AIC · ⊞ 5.3K

@github-actions github-actions Bot mentioned this pull request Aug 1, 2026
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

Test Quality Score: 92/100 — Excellent

Analyzed 8 test(s): 8 design, 0 implementation, 0 violation(s).

📊 Metrics (8 tests)
Metric Value
Analyzed 8 (JS: 8)
✅ Design 8 (100%)
⚠️ Implementation 0 (0%)
Edge/error coverage 8 (100%)
Duplicate clusters 0
Inflation No (1:1 code:test ratio)
🚨 Violations 0
📋 Test Classifications
Test File Classification Notes
valid: already uses getErrorMessage no-err-stack-then-string-fallback.test.ts:19 design_test Happy path baseline
valid: instanceof .message form is handled by prefer-get-error-message no-err-stack-then-string-fallback.test.ts:26 design_test Boundary: different property
valid: mismatched variable names are excluded no-err-stack-then-string-fallback.test.ts:33 design_test Boundary: fallback variable mismatch
valid: mismatched object in err.stack check is excluded no-err-stack-then-string-fallback.test.ts:40 design_test Boundary: test object mismatch
valid: mismatched consequent variable is excluded no-err-stack-then-string-fallback.test.ts:47 design_test Boundary: consequent variable mismatch
valid: logical-OR form is intentionally out of scope no-err-stack-then-string-fallback.test.ts:54 design_test Boundary: out-of-scope pattern
valid: test with different property than stack is excluded no-err-stack-then-string-fallback.test.ts:61 design_test Boundary: non-stack property
invalid: instanceof Error form with .stack consequent is flagged no-err-stack-then-string-fallback.test.ts:68 design_test Primary pattern + suggestions
invalid: instanceof Error form in template literal is flagged no-err-stack-then-string-fallback.test.ts:92 design_test Context variant
valid: instanceof non-Error check with .stack is excluded no-err-stack-then-string-fallback.test.ts:116 design_test Boundary: non-Error class check
invalid: core.setFailed(err && err.stack ? err.stack : String(err)) is flagged no-err-stack-then-string-fallback.test.ts:123 design_test Alternative pattern + suggestions
invalid: standalone assignment is flagged no-err-stack-then-string-fallback.test.ts:147 design_test Pattern variant
invalid: different variable name (error) is also flagged no-err-stack-then-string-fallback.test.ts:171 design_test Variable naming variance
invalid: no getErrorMessage in scope — diagnostic fires but no suggestion offered no-err-stack-then-string-fallback.test.ts:195 design_test NEW: Core fix validation

🎯 Analysis Summary

PR Fix: Gates the replaceWithGetErrorMessage suggestion on hasResolvableLocalBinding(node, "getErrorMessage") to prevent false suggestions when the helper function is not in scope.

Test Coverage:

  • 7 existing tests updated: All invalid test cases now include const { getErrorMessage } = require("./error_helpers.cjs"); in the code to establish the scope where suggestions should be offered. This reflects the real-world pattern where developers would have the import available.
  • 1 new test (critical): Lines 195–216 add comprehensive coverage for the fix itself. Two code samples verify that when getErrorMessage is NOT in scope, the diagnostic still fires (preserving user awareness) but suggestions: [] to prevent an impossible auto-fix.

Why This Matters:

  • The new test is a behavioral contract test for the core fix.
  • Without it, someone could remove the hasResolvableLocalBinding guard and tests would still pass (existing tests wouldn't catch the regression because they all have the import).
  • This test directly protects the design invariant: "only suggest an auto-fix if the fix is actually applicable."

Verdict

passed. 0% implementation tests (threshold: 30%). All tests verify design invariants. The new test at line 195 is a critical regression safeguard for the PR's core fix.

🧪 Test quality analysis by Test Quality Sentinel · haiku45 · 34.6 AIC · ⌖ 6.8 AIC · ⊞ 8.4K ·
Comment /review to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Test Quality Sentinel: 92/100. 0% implementation tests (threshold: 30%). All 8 tests are design tests verifying behavioral contracts. The new test at line 195 is a critical regression safeguard for the PR's core fix—it validates that suggestions are only offered when getErrorMessage is resolvable in scope.

@pelikhan

pelikhan commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

@copilot run pr-finisher skill

…bleAtNode

A binding is inside its own variable declarator's initializer when the
reported node's range falls within definition.node's range. Guard against
this so that `const getErrorMessage = err instanceof Error ? err.stack : String(err)`
does not receive a replaceWithGetErrorMessage suggestion that would
produce `const getErrorMessage = getErrorMessage(err)` (TDZ ReferenceError).

Add regression test covering the TDZ case.

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Aug 1, 2026

Copy link
Copy Markdown
Contributor Author

@copilot run pr-finisher skill

Done. Here's what was addressed:

TDZ fix (no-err-stack-then-string-fallback.ts): isDefinitionAvailableAtNode now checks that the reported node does not fall inside the variable declarator's own range. Previously, const getErrorMessage = err instanceof Error ? err.stack : String(err) would pass the range check (the identifier getErrorMessage starts before the conditional expression) and receive a suggestion that would produce const getErrorMessage = getErrorMessage(err) — a guaranteed ReferenceError at runtime. The guard is: if node.range is contained within definition.node.range (the VariableDeclarator), the binding is in the temporal dead zone and the suggestion is suppressed. A regression test covering this case was added.

Lock file (.github/workflows/daily-byok-ollama-test.lock.yml): The merge commit 1ec7ab3 already resolved the churn by taking the ca5620d (main) version. The current PR diff on that file is limited to legitimate version bumps (1.0.751.0.77) that came in from main — no unrelated content in the final HEAD.

Commit: fix(eslint): reject variable definitions in TDZ in isDefinitionAvailableAtNode

  • ✅ Reviews — TDZ feedback addressed; lock file churn already resolved by merge
  • ✅ Checks (local) — make agent-report-progress passed (fmt, lint, test-unit, recompile); all 15 rule tests pass
  • ❓ Checks (CI) — stale after agent push; needs human re-trigger
  • ✅ Mergeable — no conflicts

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot quick triage for this PR:

  • Your follow-up says the TDZ issue was fixed and local checks passed.
  • The remaining maintainer-facing work is cleanup and confirmation:
    1. respond directly to the outstanding review observations (for example the untested ESM/import-binding path noted by Matt Pocock Skills Reviewer) or explain why they are intentionally deferred; review summary: https://github.com/github/gh-aw/actions/runs/30689558128
    2. confirm the lock-file diff is now expected and limited to main-branch version bumps
    3. if CI is stale after the agent push, run the pr-finisher skill and leave a concise status recap for maintainers
  • No failing checks were listed in the compact candidate set, so this looks close once review follow-up is explicit.

Generated by 👨‍🍳 PR Sous Chef · gpt54 · 24.4 AIC · ⌖ 8.51 AIC · ⊞ 8.1K ·
Comment /souschef to run again

@pelikhan
pelikhan merged commit 5517bf9 into main Aug 1, 2026
1 check failed
@pelikhan
pelikhan deleted the copilot/fix-no-err-stack-then-string-fallback branch August 1, 2026 08:14
Copilot stopped work on behalf of gh-aw-bot due to an error August 1, 2026 08:14
Copilot AI requested a review from gh-aw-bot August 1, 2026 08:14
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.84.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

4 participants