```ts
/**
 * Parses a segment into [key, value] pair.
 * @param segment - The segment to parse.
 * @returns A tuple containing the key and value.
 */
export function parseOption(segment: string): string[] {
  const match = segment.match(/^([^=]+)=("([^"]*)"|[^;]*)$/);
  if (!match) {
    throw new Error('Invalid option format');
  }
  const [, key, , value] = match;
  return [key, value.replace(/^"|"$/g, '')];
}

/**
 * Splits the input string into pairs of [key, value].
 * @param input - The options string to split.
 * @returns An array of [key, value] pairs.
 */
export function scanPairs(input: string): string[][] {
  if (typeof input !== 'string' || !input) {
    throw new Error('Invalid input');
  }

  const segments = input.split(/(?<!\\);/);
  const pairs: string[][] = [];
  const seenKeys = new Set<string>();

  for (const segment of segments) {
    const [key, value] = parseOption(segment);
    if (!/^[a-zA-Z_][\w]*$/.test(key)) {
      throw new Error('Invalid key');
    }
    if (seenKeys.has(key)) {
      throw new Error('Duplicate key');
    }
    if (/^".*[^"]*$/.test(value)) {
      throw new Error('Unquoted value with double quote');
    }
    pairs.push([key, value]);
    seenKeys.add(key);
  }

  return pairs;
}
```