can1357/oh-my-pi · error

Invalid SQL identifier: ${name}

Error message

Invalid SQL identifier: ${name}

What it means

assertSqlIdentifier checks that a name (table or column used in dynamic SQL) matches `/^[A-Za-z_][A-Za-z0-9_]*$/` before interpolation, throwing a generic Error otherwise. This is a SQL-injection / query-construction guard in BinaryVectorStore's constructor, not a data validator.

Source

Thrown at packages/mnemopi/src/core/binary-vectors.ts:60

}

interface VectorRow {
	memory_id: string;
	binary_vector: Uint8Array | ArrayBuffer | Buffer;
	original_dim: number | null;
	magnitude: number | null;
}

interface StatsRow {
	count: number;
	avg_bytes: number | null;
	max_bytes: number | null;
	min_bytes: number | null;
}

function assertSqlIdentifier(name: string): string {
	if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name)) {
		throw new Error(`Invalid SQL identifier: ${name}`);
	}
	return name;
}

function toFiniteNumber(value: number | string | boolean | null | undefined): number {
	const n = Number(value ?? 0);
	return Number.isFinite(n) ? n : 0;
}

function magnitude(embedding: readonly number[]): number {
	let sum = 0;
	for (let i = 0; i < embedding.length; i += 1) {
		const value = toFiniteNumber(embedding[i]);
		sum += value * value;
	}
	return Math.sqrt(sum);
}

View on GitHub (pinned to 9690622007)

Solutions

  1. Rename the table to snake_case matching `[A-Za-z_][A-Za-z0-9_]*` (letters/digits/underscore, not starting with a digit).
  2. Sanitize/derive the name programmatically: replace invalid chars with underscores and prefix if it starts with a digit.
  3. If you need schema-qualified or quoted names, this API does not support them — keep to simple identifiers.

Example fix

// before
new BinaryVectorStore(db, { table: "2024-embeddings" });
// after
new BinaryVectorStore(db, { table: "embeddings_2024" });
Defensive patterns

Strategy: validation

Validate before calling

const IDENT_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
if (!IDENT_RE.test(table)) throw new Error(`Table name must match [A-Za-z_][A-Za-z0-9_]*: ${table}`);

Type guard

function isSqlIdentifier(s: string): boolean {
  return /^[A-Za-z_][A-Za-z0-9_]*$/.test(s);
}

Try / catch

try {
  store = new BinaryVectorStore(db, { table });
} catch (e) {
  if (e instanceof Error && e.message.startsWith("Invalid SQL identifier")) {
    store = new BinaryVectorStore(db, { table: table.replace(/[^A-Za-z0-9_]/g, "_").replace(/^\d/, "t$&") });
  } else throw e;
}

Prevention

When it happens

Trigger: Constructing the binary-vectors store with a table name containing dashes, dots, spaces, quotes, or starting with a digit — anything interpolated into SQL as an identifier.

Common situations: Deriving table names from user input or file names (e.g. `my-table`, `2024_logs`), or passing namespaced names like `schema.table`.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/d3d602d142cccb8e. Report an issue: GitHub.