KeygraphHQ/shannon · error · Error
SHANNON_AI_OPENAI_FORMAT must be one of: ${Object.keys(OPENA
Error message
SHANNON_AI_OPENAI_FORMAT must be one of: ${Object.keys(OPENAI_FORMATS).join(', ')}. Got "${raw}". What it means
Rejects an invalid value for the SHANNON_AI_OPENAI_FORMAT environment variable. The variable selects which OpenAI wire format a gateway serves and accepts only the keys of OPENAI_FORMATS: 'chat-completions' or 'responses'. Any other value is thrown rather than silently ignored, so the wrong format never reaches a request.
Source
Thrown at apps/worker/src/ai/models.ts:93
/** Format assumed when a gateway is configured but no format is named. */
export const DEFAULT_OPENAI_FORMAT: OpenAiFormat = 'chat-completions';
function isOpenAiFormat(value: string): value is OpenAiFormat {
return value in OPENAI_FORMATS;
}
/**
* Read SHANNON_AI_OPENAI_FORMAT. Unset returns undefined, which lets the caller
* distinguish "not configured" from an explicit choice and reject the variable
* where it has no effect.
*/
export function resolveOpenAiFormat(): OpenAiFormat | undefined {
const raw = process.env.SHANNON_AI_OPENAI_FORMAT?.trim();
if (!raw) return undefined;
if (!isOpenAiFormat(raw)) {
throw new Error(
`SHANNON_AI_OPENAI_FORMAT must be one of: ${Object.keys(OPENAI_FORMATS).join(', ')}. Got "${raw}".`,
);
}
return raw;
}
export interface ModelSpec {
providerId: string;
modelId: string;
}
/**
* Parse a `<provider>:<model-id>` spec. Splits on the first colon only, so colons
* inside a model ID survive. The provider id is passed through as given — pi's
* registry validates it later — so this throws only on a malformed spec.
*/
export function parseModelSpec(spec: string): ModelSpec {
const trimmed = spec.trim();View on GitHub (pinned to 1ae0a142f8)
Solutions
- Set SHANNON_AI_OPENAI_FORMAT to exactly 'chat-completions' or 'responses'.
- If you do not need to override the default, unset the variable to fall back to 'chat-completions'.
- Double-check shell quoting/export so no trailing whitespace or quotes are attached.
Example fix
// before export SHANNON_AI_OPENAI_FORMAT=openai-completions # wrong: that is the pi API id, not the key // after export SHANNON_AI_OPENAI_FORMAT=chat-completions
Defensive patterns
Strategy: validation
Validate before calling
const VALID_FORMATS = ['chat-completions', 'responses'] as const;
const raw = process.env.SHANNON_AI_OPENAI_FORMAT?.trim();
if (raw && !(VALID_FORMATS as readonly string[]).includes(raw)) {
console.error(`Invalid SHANNON_AI_OPENAI_FORMAT="${raw}". Must be one of: ${VALID_FORMATS.join(', ')}`);
process.exit(1);
} Type guard
function isOpenAiFormat(value: string): value is 'chat-completions' | 'responses' {
return value === 'chat-completions' || value === 'responses';
} Prevention
- Set SHANNON_AI_OPENAI_FORMAT only when routing OpenAI through a gateway.
- Use the key name ('chat-completions'), never the mapped pi API id ('openai-completions').
- Echo the variable before launching a scan to catch typos.
When it happens
Trigger: Set SHANNON_AI_OPENAI_FORMAT to a value that is not 'chat-completions' or 'responses', then invoke resolveOpenAiFormat() directly or via resolveGatewayFormat()/resolveModelSelection() (e.g. the preflight probe of `./shannon start`).
Common situations: Using the mapped pi API id instead of the key ('openai-completions'), underscores ('chat_completions'), camelCase ('chatCompletions'), or a stale value left over from an older Shannon version after the format names changed.
Related errors
- SHANNON_AI_OPENAI_FORMAT applies to openai models only, but
- SHANNON_AI_OPENAI_FORMAT applies to gateway runs only. Set S
- SHANNON_AI_MODEL must be "<provider>:<model-id>", got "${tri
- Model not found in pi registry: provider="${providerId}" mod
- Failed to load configuration schema: ${errMsg}
AI-assisted analysis of KeygraphHQ/shannon@1ae0a142f8 (2026-08-12).
Data as JSON: /api/errors/8f4a8857b051f812.
Report an issue: GitHub.