can1357/oh-my-pi · error · OmpTypeError
"this" cannot be used as a root definition
Error message
"this" cannot be used as a root definition
What it means
Inside a definition, the self-reference 'this' resolves via an alias IR whose resolve() throws when the root definition is not yet available or when the alias resolves to itself. Using 'this' as the entire root definition means resolution is circular with no base case, so the library throws OmpTypeError.
Source
Thrown at packages/omptype/src/type.ts:2583
resolve.hasGeneric = outer?.hasGeneric;
resolve.generic = outer?.generic;
return resolve;
}
function parseGenericArgument(definition: unknown, outer?: AliasResolver): IR {
if (outer === undefined) {
try {
return parseDef(definition);
} catch (error) {
if (!(error instanceof OmpTypeError) || !error.message.includes('unknown keyword "this"')) throw error;
}
}
let root: IR | undefined;
const self: IR = {
k: "alias",
name: "this",
resolve: () => {
if (root === undefined || root === self) throw new OmpTypeError('"this" cannot be used as a root definition');
return root;
},
};
const resolve = ((name: string) => (name === "this" ? self : outer?.(name))) as AliasResolver;
if (outer !== undefined) {
resolve.hasGeneric = outer.hasGeneric;
resolve.generic = outer.generic;
} else {
// The retry only exists to serve "this"; parses of this-free member
// strings inside the definition may still share the string cache.
markThisOnlyResolver(resolve);
}
root = parseDef(definition, resolve);
if (root === self) throw new OmpTypeError('"this" cannot be used as a root definition');
return root;
}
function genericBodyIR(View on GitHub (pinned to 9690622007)
Solutions
- Give the root a concrete shape and use 'this' only nested inside it, e.g. type({ "next?": 'this' })
- Never use 'this' as the top-level definition string
- If a truly self-recursive value type is needed, structure it via properties/arrays that wrap 'this'
Example fix
// before
const T = type('this'); // throws
// after
const T = type({ value: 'number', next: 'this?' }); Defensive patterns
Strategy: validation
Validate before calling
function assertNotBareThis(def: unknown) {
if (typeof def === 'string' && def.trim() === 'this') {
throw new Error('root definition cannot be bare "this"; wrap it in a structure');
}
} Try / catch
try {
const T = type(def);
} catch (err) {
if (err instanceof OmpTypeError && err.message.includes('"this" cannot be used as a root definition')) {
throw new Error(`Make "${String(def)}" a structure that nests "this" (e.g. { next: 'this?' })`);
}
throw err;
} Prevention
- Use 'this' only in nested positions (properties, array elements)
- For recursion, prefer named aliases with a concrete base case
- Lint definition strings for a lone 'this' body
When it happens
Trigger: Parsing the definition 'this' itself (root === self), or referencing 'this' before root is assigned such that resolve() runs while root is undefined.
Common situations: Writing a recursive schema whose whole body is just 'this'; an editing slip where the actual structure was deleted leaving only the self-reference; generated code emitting a bare self-reference.
Related errors
- mapped property ${String(property.key)} has invalid kind
- mapped property ${String(property.key)} must contain a schem
- intersection has no satisfiable branches
- ParseError: Invalid intersection of default values ${String(
- cannot apply numeric bound to ${ir.k}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/3154cfd8b3c29ac6.
Report an issue: GitHub.