can1357/oh-my-pi · error · OmpTypeError
Record key must be assignable to string or symbol
Error message
Record key must be assignable to string or symbol
What it means
`type.Record(key, value)` requires the key schema to be a string or symbol type, because object property keys in JavaScript must be PropertyKeys. Any other key type (number, boolean, union with non-string members, literal of a non-key type) is rejected at schema-construction time.
Source
Thrown at packages/omptype/src/type.ts:3495
input: { k: "union", members: [element, array] },
fn: value => (globalThis.Array.isArray(value) ? value : [value]),
out: array,
},
[],
{},
);
},
},
Record<const key, const value>(
key: key,
value: value,
): FluentType<
Record<Extract<InferDef<key>, PropertyKey>, InferDef<value>>,
Record<Extract<InferDefIn<key>, PropertyKey>, InferDefIn<value>>
> {
const keyIR = parseDef(key);
if (keyIR.k !== "string" && keyIR.k !== "symbol") {
throw new OmpTypeError("Record key must be assignable to string or symbol");
}
const valueIR = parseDef(value);
const ir: IR =
keyIR.k === "symbol"
? { k: "object", props: [], symbolIndex: valueIR, extras: "keep" }
: { k: "object", props: [], index: valueIR, extras: "keep" };
return makeType<
Record<Extract<InferDef<key>, PropertyKey>, InferDef<value>>,
Record<Extract<InferDefIn<key>, PropertyKey>, InferDefIn<value>>
>(ir, [], {});
},
Partial<const definition>(
definition: definition,
): FluentType<Partial<InferDef<definition>>, Partial<InputObject<InferDefIn<definition>>>> {
return makeType<Partial<InferDef<definition>>, Partial<InputObject<InferDefIn<definition>>>>(
setObjectOptionality(parseDef(definition), true, "partial"),
[],
{},View on GitHub (pinned to 9690622007)
Solutions
- Use a string key schema: `type.Record("string", value)`.
- For restricted keys use `"string.numeric"`-style or a string union of literals if the key type is `'a' | 'b'`.
- Wrap non-string key semantics manually: parse keys with `String(k)` before validation.
Example fix
// before
type.Record("number", "string")
// after
type.Record("string", "string") Defensive patterns
Strategy: type-guard
Validate before calling
function isRecordKeyDef(def: unknown): boolean { return def === 'string' || def === 'symbol' || (typeof def === 'string' && /^'[^']+'$/.test(def)); } Type guard
const isStringKey = (def: string): boolean => def === 'string' || def === 'symbol' || def === 'string.numeric';
Try / catch
try { const r = type.Record(keyDef, valueDef); } catch (e) { if (e instanceof OmpTypeError) fallbackToStringKey(); else throw e; } Prevention
- Always use 'string' (or 'symbol') as the key schema in type.Record
- Remember Record<number, T> from TS/Zod must become a string-keyed record in omptype
- Centralize record-key definitions in a constant to avoid drift
When it happens
Trigger: Calling `type.Record("number", "string")` or `type.Record("boolean | string", "string")` — the key IR parses to something other than `string` or `symbol`.
Common situations: Porting from Zod/TS where `Record<number, T>` is legal at the type level; omptype requires the key schema be a string type (numeric coercion is not modeled), so developers porting validators hit this.
Related errors
- anthropic-messages: ${data.summary}
- Schema contains a circular object graph — cannot enforce str
- Schema node has no type, combinator, or $ref — cannot enforc
- Validation failed for tool "${toolCall.name}":\n${errors}\n\
- ClinePass model catalog response is missing clinePass
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/7ef04c34aa827173.
Report an issue: GitHub.