tobi/qmd · error · Error

${location} (${search.type}): ${error}

Error message

${location} (${search.type}): ${error}

What it means

For search entries of type 'vec' or 'hyde', validateSemanticQuery() checks the query and its error is thrown prefixed with the location and type. Typically these types require a non-empty, bounded-length query suitable for embedding.

Source

Thrown at src/store.ts:5893

  const collections = options?.collections;

  if (searches.length === 0) return [];

  // Validate queries before executing
  for (const search of searches) {
    const location = search.line ? `Line ${search.line}` : 'Structured search';
    if (/[\r\n]/.test(search.query)) {
      throw new Error(`${location} (${search.type}): queries must be single-line. Remove newline characters.`);
    }
    if (search.type === 'lex') {
      const error = validateLexQuery(search.query);
      if (error) {
        throw new Error(`${location} (lex): ${error}`);
      }
    } else if (search.type === 'vec' || search.type === 'hyde') {
      const error = validateSemanticQuery(search.query);
      if (error) {
        throw new Error(`${location} (${search.type}): ${error}`);
      }
    }
  }

  const rankedLists: RankedResult[][] = [];
  const rankedListMeta: RankedListMeta[] = [];
  const docidMap = new Map<string, string>(); // filepath -> docid
  const hasVectors = !!store.db.prepare(
    `SELECT name FROM sqlite_master WHERE type='table' AND name='vectors_vec'`
  ).get();

  // Helper to run search across collections (or all if undefined)
  const collectionList = collections ?? [undefined]; // undefined = all collections

  // Step 1: Run FTS for all lex searches (sync, instant)
  for (const search of searches) {
    if (search.type === 'lex') {
      for (const coll of collectionList) {

View on GitHub (pinned to dbfd0b4736)

Solutions

  1. Filter out empty/blank queries before calling searchMulti
  2. Truncate long queries to the model's limit
  3. Run validateSemanticQuery first and surface its message to the user

Example fix

// before
searchMulti([{ type: 'vec', query: '' }]);
// after
searchMulti([{ type: 'vec', query: q.trim().slice(0, 512) }].filter(s => s.query));
Defensive patterns

Strategy: validation

Validate before calling

const q2 = q.trim(); if (q2 && q2.length <= LIMIT) searchMulti([{ type: 'vec', query: q2 }]);

Type guard

const isSemanticQueryValid = (q: string) => q.trim().length > 0 && q.length <= 2000;

Try / catch

try { searchMulti(s); } catch (e) { if (/\(vec\)|\(hyde\)/.test((e as Error).message)) return emptyResults(e); throw e; }

Prevention

When it happens

Trigger: Passing an empty, whitespace-only, or over-limit query string with type 'vec' or 'hyde' to searchMulti().

Common situations: Empty user input passed through to vector search; extremely long documents pasted as the query exceeding the length cap; building searches programmatically and including blank entries.

Related errors


AI-assisted analysis of tobi/qmd@dbfd0b4736 (2026-08-28). Data as JSON: /api/errors/116ca855bd2f118b. Report an issue: GitHub.