can1357/oh-my-pi · error · OmpTypeError
A default may only be specified for an object property or tu
Error message
A default may only be specified for an object property or tuple element
What it means
When parseDef parses a string definition (or array expression) it rejects any result that carries a default: defaults are only meaningful in positions that map to a storage slot — an object property or a tuple element. A bare top-level definition like "string=foo" has nothing to attach the default to, so it throws.
Source
Thrown at packages/omptype/src/ir.ts:1497
const object: IR = {
k: "object",
props,
index: indexes?.string,
symbolIndex: indexes?.symbol,
patternIndexes: indexes === undefined || indexes.patterns.length === 0 ? undefined : indexes.patterns,
extras,
};
object[kSimple] = simple;
object[kSimpleOwner] = object;
return object;
}
/** Parse a definition, optionally resolving names from an enclosing scope. */
export function parseDef(def: unknown, resolve?: AliasResolver): IR {
if (typeof def === "string") {
const parsed = parseStringDef(def, resolve);
if (parsed.hasDefault) {
throw new OmpTypeError("A default may only be specified for an object property or tuple element");
}
if (parsed.optional) {
throw new OmpTypeError(`optional "?" marker is only valid on object property values`);
}
return parsed.ir;
}
if (Array.isArray(def)) {
if (def.length === 3 && def[1] === "=") {
throw new OmpTypeError("A default may only be specified for an object property or tuple element");
}
return parseArrayExpression(def, resolve);
}
if (def instanceof RegExp) return patternIR(def);
if (def instanceof Date) return { k: "lit", v: def };
if (isEmbedded(def)) return embed(def);
if (typeof def === "function") {
const resolved = Reflect.apply(def, undefined, []);
if (!isEmbedded(resolved)) {View on GitHub (pinned to 9690622007)
Solutions
- Remove the "=default" suffix from the standalone definition
- Wrap it as an object property or tuple element where defaults are allowed
- Split into the plain type plus a separate default value handled by your own code
Example fix
// before
const T = type("string='hello'")
// after
const T = type({ key: "string='hello'" }) Defensive patterns
Strategy: type-guard
Validate before calling
function assertNoTopLevelDefault(def) {
if (typeof def === "string" && /=/.test(def.split("|")[0])) {
// conservative check for "=default" suffix outside property position
throw new Error("remove the =default from the standalone definition");
}
if (Array.isArray(def) && def.length === 3 && def[1] === "=") {
throw new Error("defaulted array form only valid as property/tuple value");
}
} Type guard
const isDefaultedForm = (d) => (Array.isArray(d) && d.length === 3 && d[1] === "=");
Try / catch
try { const T = type(def); } catch (e) {
if (e.message.includes("A default may only be specified")) {
// move def into an object property or tuple element, or strip the default
} else throw e;
} Prevention
- Only write "=default" inside object property values or tuple elements
- When lifting property values into standalone constants, strip the default segment
- Review copy-pasted property strings for trailing "=..." suffixes
When it happens
Trigger: Calling parseDef (directly or via type()) with a string def that parseStringDef parses with hasDefault set, or an array def of length 3 with "=" at index 1 — i.e. a default written outside an object property or tuple element position.
Common situations: Copying a property's string including its "=value" suffix into a standalone type; passing a defaulted expression where a plain type is expected (function parameter, union member, alias body).
Related errors
- optional key ${String(key)} cannot specify a default
- unsupported default literal in "${this.#src}"
- invalid index signature pattern ${keyDefinition}
- duplicate object key ${String(key)}
- optional "?" marker is only valid on object property values
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/8fdcb49ded64f023.
Report an issue: GitHub.