continuedev/continue · error · Error
Either streamCompletion or streamChat must be defined in a c
Error message
Either streamCompletion or streamChat must be defined in a custom LLM in config.ts
What it means
Thrown by CustomLLM._streamComplete when the user-supplied custom LLM object in config.ts defines neither streamCompletion nor streamChat. The custom provider has no way to generate text, so the first completion attempt fails immediately with this config error.
Source
Thrown at core/llm/llms/CustomLLM.ts:83
(...args) => this.fetch(...args),
)) {
yield content;
}
} else if (this.customStreamChat) {
for await (const content of this.customStreamChat(
[{ role: "user", content: prompt }],
signal,
options,
(...args) => this.fetch(...args),
)) {
if (typeof content === "string") {
yield content;
} else {
yield renderChatMessage(content);
}
}
} else {
throw new Error(
"Either streamCompletion or streamChat must be defined in a custom LLM in config.ts",
);
}
}
}
export default CustomLLMClass;
View on GitHub (pinned to 5522c6f44c)
Solutions
- Implement at least one of async function* streamCompletion(prompt) or async function* streamChat(messages) on the custom object
- Check spelling and that they are generator functions (use function* syntax or yield)
- Return/throw cleanly from config.ts if the custom provider isn't configured, instead of an empty object
- Add a startup smoke test that calls streamComplete once
Example fix
// before
config.llm = { provider: 'custom', options: { streamCompletion2: async function* () {} } };
// after
config.llm = { provider: 'custom', options: { streamCompletion: async function* (prompt) { yield 'ok'; } } }; Defensive patterns
Strategy: validation
Validate before calling
const custom = config.llm.options;
if (typeof custom.streamCompletion !== 'function' && typeof custom.streamChat !== 'function') {
throw new Error('Custom LLM must implement streamCompletion or streamChat');
} Type guard
function isValidCustomLLM(o: unknown): o is { streamChat?: Function; streamCompletion?: Function } {
return !!o && (typeof (o as any).streamChat === 'function' || typeof (o as any).streamCompletion === 'function');
} Try / catch
try { yield* llm.streamComplete(p); }
catch (e) {
if (e instanceof Error && e.message.includes('custom LLM')) throw new ConfigError(e.message);
throw e;
} Prevention
- Assert the required method exists in a config test
- Name stream methods exactly streamCompletion/streamChat
- Add a smoke-test completion in CI
When it happens
Trigger: Defining a custom LLM entry in config.ts with only non-streaming methods (e.g. just complete), misspelling streamCompletion/streamChat (e.g. streamCompletions), or passing an empty object/class instance as the custom provider.
Common situations: Users porting a non-streaming custom provider from another framework, method renamed during refactor, or providing the functions as arrow properties under the wrong key so the presence check fails.
Related errors
- Invalid MCP server configuration
- AI SDK provider requires a model in the format '<provider>/<
- Profile ${profileId} not found
- No reranker set up
- No chat model selected
AI-assisted analysis of continuedev/continue@5522c6f44c (2026-08-27).
Data as JSON: /api/errors/f609fa75e70004e5.
Report an issue: GitHub.