can1357/oh-my-pi · error · TypeError
Invalid service tier "${String(tier)}" for family "${String(
Error message
Invalid service tier "${String(tier)}" for family "${String(family)}" What it means
setServiceTier validates its arguments before delegating to the runtime: family must be a known service-tier family and, when tier is defined, it must be a valid tier for that family. Anything else throws a TypeError reporting both the offending values.
Source
Thrown at packages/coding-agent/src/extensibility/extensions/loader.ts:315
setModel(model: Model): Promise<boolean> {
return this.runtime.setModel(model);
}
getThinkingLevel(): ThinkingLevel | undefined {
return this.runtime.getThinkingLevel();
}
setThinkingLevel(level: ThinkingLevel, persist?: boolean): void {
this.runtime.setThinkingLevel(level, persist);
}
getServiceTiers(): Readonly<ServiceTierByFamily> {
return { ...this.runtime.getServiceTiers() };
}
setServiceTier(family: ServiceTierFamily, tier: ServiceTier | undefined): void {
if (!isServiceTierFamily(family) || (tier !== undefined && !isServiceTierForFamily(family, tier))) {
throw new TypeError(`Invalid service tier "${String(tier)}" for family "${String(family)}"`);
}
this.runtime.setServiceTier(family, tier);
}
getSessionName(): string | undefined {
return this.runtime.getSessionName();
}
setSessionName(name: string): Promise<void> {
return this.runtime.setSessionName(name);
}
registerProvider(name: string, config: ProviderConfig): void {
this.runtime.registerProvider(name, config, this.extension.path);
}
unregisterProvider(name: string): void {
this.runtime.unregisterProvider(name, this.extension.path);View on GitHub (pinned to 9690622007)
Solutions
- Use getServiceTiers() to enumerate valid families and their allowed tiers before calling setServiceTier.
- Correct the family name/tier spelling against the ServiceTierFamily and ServiceTier types.
- Validate the config-provided tier against the allowed set for the family before invoking the API; pass undefined to clear.
Example fix
// before
runtime.setServiceTier('openai', 'priority' as any); // may not be valid
// after
const tiers = runtime.getServiceTiers();
const allowed = tiers['openai'];
if (allowed && allowed.includes('priority')) runtime.setServiceTier('openai', 'priority'); Defensive patterns
Strategy: validation
Validate before calling
const tiers = runtime.getServiceTiers();
const allowed = tiers[family];
if (allowed && (tier === undefined || allowed.includes(tier))) {
runtime.setServiceTier(family, tier);
} Type guard
function isValidTierCall(f: string, t: unknown, tiers: ServiceTierByFamily): boolean {
const allowed = tiers[f as keyof ServiceTierByFamily];
return Array.isArray(allowed) && (t === undefined || (allowed as string[]).includes(t as string));
} Try / catch
try {
runtime.setServiceTier(family, tier);
} catch (err) {
if (err instanceof TypeError && err.message.includes('Invalid service tier')) {
logger.error('bad service tier/family', { family, tier });
} else throw err;
} Prevention
- Query getServiceTiers() instead of hardcoding families/tiers.
- Type family/tier with the ServiceTierFamily/ServiceTier unions, not strings.
- Validate env/config-sourced tiers before use; unset values become 'undefined' strings.
- Don't copy tiers across families — each family has its own allowed set.
When it happens
Trigger: Calling runtime.setServiceTier(family, tier) with a misspelled family name, a tier that is not offered for that family, or tier values typed as wrong runtime values (e.g. numbers/objects stringified in the message).
Common situations: Hardcoded tier string with a typo ('priority' vs 'flex'); copying a tier valid for one family (e.g. OpenAI) and applying it to another; tier read from env/config that is unset so String(undefined) appears in the message.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Composer shape id must be a non-empty trimmed string
- Composer shape "${id}" must have a label
- Cannot replace built-in composer shape "${id}"
- This extension host does not support service-tier actions
- Unsupported language '{value}'. Supported: {}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/17b356fe189603cb.
Report an issue: GitHub.