fix(core): Cohere and Voyage rerankers bypass non-positive limit check on NaN topN and send invalid null payload

Fermée
#582 3 commentaires 0 réactions 1 personne assignée Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

@bhushan4work y travaille déjà.

Depuis le 3/11/2026.

  • #589 par @bhushan4work — fusionnée

Évaluation

Cette issue n'a pas encore été évaluée.

Description

bug core
Which part?

@chatcops/core

Package version

No response

What happened?
Problem

In both cohereReranker and voyageReranker, candidate reranking enforces the requested limit using:
const limit = Math.floor(topN);
if (chunks.length === 0 || limit <= 0) return [];
If topN evaluates to NaN (such as when parsing unvalidated query/input parameters into retrieval plans), Math.floor(NaN) evaluates to NaN. In JavaScript /
IEEE 754 arithmetic, relational comparisons with NaN (NaN <= 0) always evaluate to false.

Consequently, the early return check is bypassed:

  1. Math.min(limit, chunks.length) calculates Math.min(NaN, chunks.length), which returns NaN.
  2. When serialized for outbound HTTP calls, JSON.stringify converts NaN to null:
    • Cohere receives: {"top_n": null}
    • Voyage receives: {"top_k": null}
  3. Both Cohere and Voyage AI endpoints reject null values with HTTP 400 Bad Request (e.g. invalid request: top_n must be a positive integer), triggering an
    unhandled provider error in postWithRetries that aborts the chat/retrieval turn.
    By contrast, workersAiReranker correctly protects against this:
    const requestedLimit = Number.isFinite(topN) && topN > 0 ? Math.floor(topN) : 0;
    if (!requestedLimit || !chunks.length) return [];
Actual Behavior

• Actual Behavior: Calling rerank(query, chunks, NaN) bypasses the non-positive limit guard, triggers an outbound HTTP request with top_n: null or top_k:
null, and fails with HTTP 400 Bad Request.

Impact

• Any unvalidated or non-numeric topK / topN value passed directly to rerankers or computed via plan() results in an unnecessary outbound API call that fails
with an unhandled HTTP 400 error.
• Causes behavioral inconsistency across @chatcops/core rerankers (workersAiReranker returns [], while cohereReranker and voyageReranker fail with provider
errors).

Acceptance Criteria

• cohereReranker and voyageReranker validate that topN is a positive finite number (e.g., using Number.isFinite(topN) && topN > 0) before making outbound
requests.
• Invoking rerank with NaN or non-finite topN returns [] immediately without sending network requests.
• Test suites in cohere-reranker.test.ts and voyage-reranker.test.ts include assertions for non-finite topN values.

What did you expect?

• Expected Behavior: Calling rerank(query, chunks, NaN) should recognize non-finite / invalid counts, return [] immediately, and avoid making unnecessary
outbound API calls.

How can we reproduce it?
1. Initialize a reranker instance:
    const reranker = cohereReranker({ apiKey: 'dummy-key', fetch: mockFetch });

  2. Call rerank with non-empty chunks and NaN:
    await reranker.rerank('query', [{ id: '1', text: 'chunk' }], NaN);

  3. Inspect mockFetch: instead of returning [] without dispatching a network call (like topN = 0 does), a request is dispatched with body:
    { "model": "rerank-v5.0-pro", "query": "query", "documents": ["chunk"], "top_n": null }
Environment

No response

Langage dominant
TypeScript
Étoiles
13
Forks
7
Merge moyen
3 h 14 min
PR mergées (30 j)
332

Préparer son environnement

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de codercops/chatcops

Toutes les issues de codercops/chatcops

Issues similaires

Plus d'issues TypeScript

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.