can1357/oh-my-pi · error · OmpTypeError
alias "${name}" is declared as both public and private
Error message
alias "${name}" is declared as both public and private What it means
In a scope, every alias key maps to a canonical visible name (a leading `#` marks the alias private and is stripped). Two source keys that reduce to the same visible name — e.g. `"foo"` and `"#foo"` — collide, and omptype throws when building the scope's alias table.
Source
Thrown at packages/omptype/src/type.ts:3791
materialized: boolean;
}
function isRuntimeModule(value: unknown): value is RuntimeModule {
return typeof value === "object" && value !== null && MODULE_SCOPE in value;
}
function buildScope(aliases: Record<string, unknown>, options?: ScopeOptions): TypeScope {
const scopeMeta: TypeMeta = options?.clone === undefined ? EMPTY_META : { clone: options.clone };
const withScopeConfig = (ir: IR): IR =>
options?.divisor === undefined ? ir : configureSelected(ir, options.divisor, { kind: "divisor" });
const entries = new Map<string, ScopeAlias>();
for (const sourceName in aliases) {
const isPrivate = sourceName.startsWith("#");
const visibleName = isPrivate ? sourceName.slice(1) : sourceName;
const declaration = parseGenericDeclaration(visibleName);
const external = isRuntimeGeneric(aliases[sourceName]) ? aliases[sourceName] : undefined;
const name = declaration?.name ?? visibleName;
if (entries.has(name)) throw new OmpTypeError(`alias "${name}" is declared as both public and private`);
entries.set(name, {
name,
sourceName,
private: isPrivate,
genericParameters: declaration?.parameters ?? external?.[GENERIC_META].parameters,
definition: aliases[sourceName],
generic: external,
materialized: false,
});
}
const references = new Map<string, IR>();
const targets = new Map<string, IR>();
let scopeValue: TypeScope;
const materialize = (entry: ScopeAlias): unknown => {
if (entry.materialized) return entry.definition;
entry.materialized = true;View on GitHub (pinned to 9690622007)
Solutions
- Delete the duplicate key from the aliases object passed to `type.scope`.
- Rename one of the colliding aliases.
- Normalize keys (strip/standardize `#` prefixes) before building the scope object when keys are dynamic.
Example fix
// before
type.scope({ "foo": "string", "#foo": "number" })
// after
type.scope({ "foo": "string", "#bar": "number" }) Defensive patterns
Strategy: validation
Validate before calling
function hasAliasCollision(aliases: Record<string, unknown>) { const seen = new Set(); for (const k of Object.keys(aliases)) { const n = k.startsWith('#') ? k.slice(1) : k; if (seen.has(n)) return true; seen.add(n); } return false; } Try / catch
try { const $ = type.scope(aliases); } catch (e) { if (e instanceof OmpTypeError && e.message.includes('both public and private')) dedupeAliases(aliases); else throw e; } Prevention
- Strip '#' prefixes when merging alias maps from multiple sources and dedupe first
- Do not conditionally add a '#' variant of an existing public alias
- Keep private aliases in a separate namespace with distinct visible names
When it happens
Trigger: Defining a scope with both `{ "foo": ..., "#foo": ... }`, or constructing scope keys dynamically so one ends up with a `#` prefix duplicating an existing public alias.
Common situations: Merging alias maps from multiple modules where one exports a private variant and another a public one with the same name; template-driven scope generation that conditionally prefixes `#`.
Related errors
- alias "${entry.name}" is not generic
- unknown alias "${name}"
- anthropic-messages: ${data.summary}
- Anthropic cache refresh response omitted usage
- Schema contains a circular object graph — cannot enforce str
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/24a43f49d9be572f.
Report an issue: GitHub.