Skip to content

refactor: remove unsafe overload casts in parallel probe#383

Closed
ndycode wants to merge 1 commit intomainfrom
fix/type-safety-forced-casts
Closed

refactor: remove unsafe overload casts in parallel probe#383
ndycode wants to merge 1 commit intomainfrom
fix/type-safety-forced-casts

Conversation

@ndycode
Copy link
Copy Markdown
Owner

@ndycode ndycode commented Apr 6, 2026

Problem

parallel-probe relied on unsafe forced casts to distinguish its overload inputs and to normalize probe failures.

That keeps behavior working, but it weakens the type guarantees around a hot path that is already small enough to model explicitly.

Fix

Replace the forced casts with explicit type guards and a small error-normalization helper.

Changes

  • lib/parallel-probe.ts
    • added isAccountManager(...)
    • added isGetTopCandidatesParams(...)
    • added toProbeError(...)
    • removed unsafe overload casts in getTopCandidates(...)
    • normalized single-candidate probe failures without as Error
  • test/parallel-probe.test.ts
    • added coverage for named-params overload usage
    • added coverage for non-Error probe failures being normalized

Validation

npx vitest run test/parallel-probe.test.ts
Test Files  1 passed (1)
Tests      23 passed (23)

npx vitest run
Test Files  222 passed (222)
Tests      3315 passed (3315)

note: greptile review for oc-chatgpt-multi-auth. cite files like lib/foo.ts:123. confirm regression tests + windows concurrency/token redaction coverage.

Greptile Summary

this PR replaces unsafe forced casts (as GetTopCandidatesParams, as AccountManager, as Error) in lib/parallel-probe.ts with explicit runtime type guards (isAccountManager, isGetTopCandidatesParams) and an error-normalization helper (toProbeError). two new test cases cover non-Error throw normalization in single-candidate probing and the named-params overload path. no windows filesystem or token safety concerns are introduced; no concurrency issues are added — the parallel probe path is structurally unchanged.

  • the type-narrowing change is correct and the new tests pass
  • isGetTopCandidatesParams failure emits \"requires accountManager\" even when modelFamily or maxCandidates is the bad field — misleading for callers
  • the new isAccountManager guard in the positional-args else branch has no vitest test (named-params path is covered; positional path is not)
  • the pre-existing defense-in-depth guard at lines 113-118 is now dead code after the refactor

Confidence Score: 4/5

safe to merge with minor fixes recommended — the core type-narrowing logic is correct and tests pass

the refactor is sound and improves type safety; the two gaps (misleading error message in the named-params failure path, missing positional-args TypeError test) are low-risk but worth addressing before merge. no concurrency, token safety, or windows filesystem concerns introduced.

lib/parallel-probe.ts lines 95-97 (error message) and 104-106 (missing test coverage)

Important Files Changed

Filename Overview
lib/parallel-probe.ts adds isAccountManager/isGetTopCandidatesParams guards and toProbeError; misleading error message in the named-params failure path and a now-dead guard at lines 113-118
test/parallel-probe.test.ts adds non-Error normalization test and named-params overload test; missing coverage for positional-args TypeError branch introduced in this PR

Sequence Diagram

sequenceDiagram
    participant Caller
    participant getTopCandidates
    participant isGetTopCandidatesParams
    participant isAccountManager
    participant AccountManager

    Caller->>getTopCandidates: named params call
    getTopCandidates->>isGetTopCandidatesParams: validate params object
    isGetTopCandidatesParams->>isAccountManager: validate accountManager field
    isAccountManager-->>isGetTopCandidatesParams: bool
    isGetTopCandidatesParams-->>getTopCandidates: bool
    alt invalid params (misleading error message)
        getTopCandidates-->>Caller: TypeError("requires accountManager")
    else valid
        getTopCandidates->>AccountManager: getAccountsSnapshot()
        AccountManager-->>getTopCandidates: ManagedAccount[]
        getTopCandidates-->>Caller: top-N ManagedAccount[]
    end

    Caller->>getTopCandidates: positional args call
    getTopCandidates->>isAccountManager: validate first arg
    isAccountManager-->>getTopCandidates: bool
    alt invalid (no test coverage for this path)
        getTopCandidates-->>Caller: TypeError("requires accountManager")
    else valid
        getTopCandidates->>AccountManager: getAccountsSnapshot()
        AccountManager-->>getTopCandidates: ManagedAccount[]
        getTopCandidates-->>Caller: top-N ManagedAccount[]
    end
Loading

Fix All in Codex

Prompt To Fix All With AI
This is a comment left during a code review.
Path: lib/parallel-probe.ts
Line: 95-97

Comment:
**misleading error message when non-accountManager field is invalid**

`isGetTopCandidatesParams` validates four fields — `accountManager`, `modelFamily`, `model`, and `maxCandidates` — but the thrown message always says `"getTopCandidates requires accountManager"`. a caller that passes `{ accountManager: validMgr, modelFamily: 123, model: null, maxCandidates: 2 }` hits this throw because `modelFamily` is not a string, but the error blames `accountManager`. this is a new throw path introduced by this PR, and the message is wrong in those cases.

```suggestion
		if (!isGetTopCandidatesParams(accountManagerOrParams)) {
			throw new TypeError("getTopCandidates: invalid named params (check accountManager, modelFamily, model, maxCandidates)");
		}
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: lib/parallel-probe.ts
Line: 104-106

Comment:
**missing vitest coverage for positional-args TypeError branch**

this new throw path has no test. the named-params equivalent is covered by `"throws clear TypeError when accountManager is missing required shape"` (test line ~450), but nothing exercises passing a non-`AccountManager` object via positional args. per the repo's 80% coverage threshold and the convention to call out missing vitest coverage explicitly:

```ts
it("throws TypeError when positional accountManager is missing required shape", () => {
  expect(() =>
    getTopCandidates({} as unknown as AccountManager, "codex", null, 2)
  ).toThrowError("getTopCandidates requires accountManager");
});
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: lib/parallel-probe.ts
Line: 113-118

Comment:
**dead code — guard is unreachable after the type-guard refactor**

both branches above either throw (if the type guard fails) or set `resolvedAccountManager` to a value that already satisfies `isAccountManager`. the `!resolvedAccountManager` and `getAccountsSnapshot !== "function"` conditions can never be true when execution reaches this point. the guard predates this PR, but the refactor makes it dead — worth removing to avoid misleading future readers into thinking this path can fire.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "refactor: remove unsafe overload casts i..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

parallel-probe used forced casts to distinguish overload inputs and to
normalize probe failures. Replace those with explicit type guards and
error normalization so the module keeps the same behavior without
leaning on unsafe assertions.
@chatgpt-codex-connector
Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 6, 2026

Warning

Rate limit exceeded

@ndycode has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 1 minutes and 46 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 1 minutes and 46 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 7a2719c2-c7c0-4d82-9864-63b754327737

📥 Commits

Reviewing files that changed from the base of the PR and between 478f44c and 361d3ca.

📒 Files selected for processing (2)
  • lib/parallel-probe.ts
  • test/parallel-probe.test.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/type-safety-forced-casts
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch fix/type-safety-forced-casts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Comment thread lib/parallel-probe.ts
Comment on lines +95 to +97
if (!isGetTopCandidatesParams(accountManagerOrParams)) {
throw new TypeError("getTopCandidates requires accountManager");
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 misleading error message when non-accountManager field is invalid

isGetTopCandidatesParams validates four fields — accountManager, modelFamily, model, and maxCandidates — but the thrown message always says "getTopCandidates requires accountManager". a caller that passes { accountManager: validMgr, modelFamily: 123, model: null, maxCandidates: 2 } hits this throw because modelFamily is not a string, but the error blames accountManager. this is a new throw path introduced by this PR, and the message is wrong in those cases.

Suggested change
if (!isGetTopCandidatesParams(accountManagerOrParams)) {
throw new TypeError("getTopCandidates requires accountManager");
}
if (!isGetTopCandidatesParams(accountManagerOrParams)) {
throw new TypeError("getTopCandidates: invalid named params (check accountManager, modelFamily, model, maxCandidates)");
}
Prompt To Fix With AI
This is a comment left during a code review.
Path: lib/parallel-probe.ts
Line: 95-97

Comment:
**misleading error message when non-accountManager field is invalid**

`isGetTopCandidatesParams` validates four fields — `accountManager`, `modelFamily`, `model`, and `maxCandidates` — but the thrown message always says `"getTopCandidates requires accountManager"`. a caller that passes `{ accountManager: validMgr, modelFamily: 123, model: null, maxCandidates: 2 }` hits this throw because `modelFamily` is not a string, but the error blames `accountManager`. this is a new throw path introduced by this PR, and the message is wrong in those cases.

```suggestion
		if (!isGetTopCandidatesParams(accountManagerOrParams)) {
			throw new TypeError("getTopCandidates: invalid named params (check accountManager, modelFamily, model, maxCandidates)");
		}
```

How can I resolve this? If you propose a fix, please make it concise.

Fix in Codex

@ndycode
Copy link
Copy Markdown
Owner Author

ndycode commented Apr 6, 2026

Superseded by #387, which rebuilds the full open PR stack onto one reviewed integration branch.

@ndycode
Copy link
Copy Markdown
Owner Author

ndycode commented Apr 6, 2026

Closing in favor of #387.

@ndycode ndycode closed this Apr 6, 2026
@ndycode ndycode deleted the fix/type-safety-forced-casts branch April 12, 2026 06:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant