can1357/oh-my-pi · error · OmpTypeError
duplicate generic parameter "${parameter.name}"
Error message
duplicate generic parameter "${parameter.name}" What it means
validateGenericParameters() rejects duplicate generic parameter names by tracking names in a Set and throwing OmpTypeError on a repeat. Duplicated placeholders are ambiguous — the body could not tell which argument to substitute where — so they are errors at declaration time.
Source
Thrown at packages/omptype/src/type.ts:2511
}
/** Schema arguments passed to a callback-bodied runtime generic. */
export interface GenericArguments {
readonly [name: string]: BaseType;
}
export interface GenericBuilder {
(definition: (arguments_: GenericArguments) => unknown, hkt?: unknown): Generic;
(definition: unknown, hkt?: unknown): Generic;
}
function validateGenericParameters(parameters: readonly GenericParameter[]): void {
const names = new Set<string>();
for (const parameter of parameters) {
if (!/^[A-Za-z_$]\w*$/.test(parameter.name)) {
throw new OmpTypeError(`invalid generic parameter "${parameter.name}"`);
}
if (names.has(parameter.name)) throw new OmpTypeError(`duplicate generic parameter "${parameter.name}"`);
names.add(parameter.name);
}
if (parameters.length === 0) throw new OmpTypeError("generic declarations require at least one parameter");
}
function parseGenericParameters(source: string): GenericParameter[] {
const trimmed = source.trim();
const body = trimmed.startsWith("<") && trimmed.endsWith(">") ? trimmed.slice(1, -1) : trimmed;
const parts: string[] = [];
let start = 0;
let depth = 0;
let quote = "";
for (let index = 0; index < body.length; index++) {
const char = body[index];
if (quote !== "") {
if (char === quote && body[index - 1] !== "\\") quote = "";
continue;
}View on GitHub (pinned to 9690622007)
Solutions
- Rename one of the duplicated parameters to a distinct identifier
- If merging parameter lists programmatically, deduplicate before joining (e.g. new Set(parts))
- Review copy/pasted declarations for leftover repeated placeholders
Example fix
// before
const T = generic('<T, T>', 'record<T, T[]>'); // throws
// after
const T = generic('<K, V>', 'record<K, V[]>'); Defensive patterns
Strategy: validation
Validate before calling
function assertUniqueParams(names: readonly string[]) {
const dupes = names.filter((n, i) => names.indexOf(n) !== i);
if (dupes.length) throw new Error(`duplicate generic parameters: ${[...new Set(dupes)].join(', ')}`);
} Try / catch
try {
const G = generic(decl, body);
} catch (err) {
if (err instanceof OmpTypeError && err.message.includes('duplicate generic parameter')) {
const name = err.message.match(/"(.*)"/)?.[1];
throw new Error(`Rename the repeated parameter "${name}" in "${decl}"`);
}
throw err;
} Prevention
- Deduplicate merged parameter lists with new Set(parts) before joining
- Use distinct names per role (K/V for key/value) to avoid collisions
- Review copy/pasted declarations for leftovers
When it happens
Trigger: Declaring a generic with the same parameter twice, e.g. generic('<T, T>', ...) or generic('<K, V, K>', ...), including duplicates introduced by string splitting when the declaration is built dynamically.
Common situations: Copy/paste when extending a generic's parameter list; concatenating parameter strings from two sources that both use 'T'; typos where an intended distinct name was never changed.
Related errors
- invalid generic parameter "${parameter.name}"
- generic declarations require at least one parameter
- generic expects ${parameters.length} arguments (received ${a
- mapped property ${String(property.key)} has invalid kind
- mapped property ${String(property.key)} must contain a schem
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/f04709699f859292.
Report an issue: GitHub.