prisma/prisma · error

proximity-chain: trailing distance with no following term at

Error message

proximity-chain: trailing distance with no following term at position ${i + 1}

What it means

Thrown by parseProximityChainArgs when, while iterating distance/term pairs, a distance token has no corresponding term. Because the loop steps by 2, this only happens when the leading args.length/parity check is bypassed (e.g. a direct caller passes an even-length array) or when an array element is explicitly undefined. It is a structural-consistency guard for the pairing loop.

Source

Thrown at examples/paradedb-demo/src/main.ts:30

import { bm25TopByScore } from './queries/bm25-top-by-score';

function parseProximityChainArgs(args: readonly string[]): {
  readonly start: string;
  readonly steps: readonly ProximityChainStep[];
} {
  if (args.length < 3 || args.length % 2 !== 1) {
    throw new Error('Usage: pnpm start -- proximity-chain <t0> <d1> <t1> [<d2> <t2> ...]');
  }
  const [start, ...rest] = args;
  if (start === undefined) {
    throw new Error('proximity-chain: <t0> is required');
  }
  const steps: ProximityChainStep[] = [];
  for (let i = 0; i < rest.length; i += 2) {
    const distRaw = rest[i];
    const term = rest[i + 1];
    if (distRaw === undefined || term === undefined) {
      throw new Error(
        `proximity-chain: trailing distance with no following term at position ${i + 1}`,
      );
    }
    const ordered = distRaw.startsWith('>');
    const distStr = ordered ? distRaw.slice(1) : distRaw;
    const distance = Number.parseInt(distStr, 10);
    if (!Number.isInteger(distance) || distance < 0) {
      throw new Error(
        `proximity-chain: distance at position ${i + 1} must be a non-negative integer (optionally prefixed '>' for ordered); got '${distRaw}'`,
      );
    }
    steps.push({ distance, term, ordered });
  }
  return { start, steps };
}

const argv = process.argv.slice(2).filter((arg) => arg !== '--');
const [cmd, ...args] = argv;

View on GitHub (pinned to 1243cdffbe)

Solutions

  1. Ensure the args after the start term come in distance/term pairs (even count of rest args).
  2. If invoked via CLI, fix the invocation to satisfy the usage message (error [16]) first.
  3. For direct callers, normalize args (strip holes/undefined) and assert even pairing before calling.
  4. Add a trailing term to consume the dangling distance, or drop the trailing distance.
Defensive patterns

Strategy: validation

Validate before calling

for (let i = 0; i < rest.length; i += 2) {
  if (rest[i] === undefined || rest[i + 1] === undefined) {
    console.error(`trailing distance with no following term at position ${i + 1}`);
    process.exit(1);
  }
}

Type guard

const isCompletePairs = (a: readonly unknown[]): a is string[] =>
  a.length % 2 === 0 && a.every((x) => typeof x === 'string');

Try / catch

try {
  const { start, steps } = parseProximityChainArgs(args);
} catch (error) {
  if (error instanceof Error && error.message.includes('trailing distance')) {
    console.error(error.message);
    process.exit(1);
  }
  throw error;
}

Prevention

When it happens

Trigger: Calling parseProximityChainArgs with an even number of rest arguments (after the start term), so the last distance token (rest[i]) has rest[i+1] (term) undefined. The reported position is i+1 within the rest array.

Common situations: Direct programmatic callers passing an even-length args array; via the normal CLI this is pre-empted by error [16]. Can appear if someone refactors the length guard or feeds args from a parsed source that drops empty strings.

Related errors


AI-assisted analysis of prisma/prisma@1243cdffbe (2026-08-01). Data as JSON: /data/errors/bba08912902135d9.json. Report an issue: GitHub.