KeygraphHQ/shannon · error · Error
SHANNON_AI_OPENAI_FORMAT applies to gateway runs only. Set S
Error message
SHANNON_AI_OPENAI_FORMAT applies to gateway runs only. Set SHANNON_AI_BASE_URL, or unset the format to call OpenAI directly.
What it means
resolveGatewayFormat rejects SHANNON_AI_OPENAI_FORMAT when calling OpenAI directly with no gateway configured. The format only matters behind a custom endpoint that can serve either wire format; a direct OpenAI call uses one fixed API, so the variable is rejected rather than silently dropped.
Source
Thrown at apps/worker/src/ai/models.ts:311
* Validate SHANNON_AI_OPENAI_FORMAT against the rest of the configuration and
* return the format a gateway run should use.
*
* The variable only reaches a request when both an OpenAI model and a gateway
* are configured, so it is rejected outside that combination rather than
* silently ignored.
*/
export function resolveGatewayFormat(providerId: string, baseUrl: string | undefined): OpenAiFormat {
const configured = resolveOpenAiFormat();
if (!configured) return DEFAULT_OPENAI_FORMAT;
if (providerId !== 'openai') {
throw new Error(
`SHANNON_AI_OPENAI_FORMAT applies to openai models only, but SHANNON_AI_MODEL selects "${providerId}". ` +
`${providerId} serves a single API, so there is no format to choose.`,
);
}
if (!baseUrl) {
throw new Error(
'SHANNON_AI_OPENAI_FORMAT applies to gateway runs only. Set SHANNON_AI_BASE_URL, or unset the format to call OpenAI directly.',
);
}
return configured;
}
/**
* Resolve SHANNON_AI_MODEL, build a ModelRuntime primed with the provider's
* credential, and look the model up in it.
*/
export async function resolveModelSelection(): Promise<ModelSelection> {
const { providerId, modelId } = resolveModelSpec();
const credentials = resolveProviderCredentials(providerId);
const format = resolveGatewayFormat(providerId, credentials.baseUrl);
const modelRuntime = await createModelRuntime(providerId, credentials.apiKey);
const model = resolveModel(modelRuntime, providerId, modelId, credentials.baseUrl, format);View on GitHub (pinned to 1ae0a142f8)
Solutions
- Set SHANNON_AI_BASE_URL to the gateway endpoint if you route OpenAI through one.
- Unset SHANNON_AI_OPENAI_FORMAT to call OpenAI directly.
Example fix
# before export SHANNON_AI_MODEL=openai:gpt-4o export SHANNON_AI_OPENAI_FORMAT=responses # SHANNON_AI_BASE_URL not set # after (pick one) export SHANNON_AI_BASE_URL=https://my-gateway.example.com # keep the format # OR unset SHANNON_AI_OPENAI_FORMAT # direct OpenAI
Defensive patterns
Strategy: validation
Validate before calling
const provider = (process.env.SHANNON_AI_MODEL ?? 'anthropic:claude-sonnet-4-6').split(':')[0];
const formatSet = !!process.env.SHANNON_AI_OPENAI_FORMAT?.trim();
const hasGateway = !!process.env.SHANNON_AI_BASE_URL?.trim();
if (formatSet && provider === 'openai' && !hasGateway) {
console.error('SHANNON_AI_OPENAI_FORMAT requires SHANNON_AI_BASE_URL. Set the gateway URL or unset the format.');
process.exit(1);
} Prevention
- Only set SHANNON_AI_OPENAI_FORMAT together with SHANNON_AI_BASE_URL.
- When removing a gateway, unset both SHANNON_AI_BASE_URL and the format variable.
When it happens
Trigger: SHANNON_AI_OPENAI_FORMAT is set, SHANNON_AI_MODEL selects an openai provider, but SHANNON_AI_BASE_URL is unset, then resolveModelSelection() runs.
Common situations: Setting the format in anticipation of a proxy/gateway but forgetting SHANNON_AI_BASE_URL; a leftover format var after removing a gateway.
Related errors
- SHANNON_AI_OPENAI_FORMAT must be one of: ${Object.keys(OPENA
- SHANNON_AI_OPENAI_FORMAT applies to openai models only, but
- 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/2946a6d11b6750b0.
Report an issue: GitHub.