janhq/jan · error · Error
ServiceHub not initialized or model/provider missing.
Error message
ServiceHub not initialized or model/provider missing.
What it means
Thrown at the very start of `sendMessages` when any of three preconditions is falsy: `this.serviceHub`, the selected model id (`useModelProvider.getState().selectedModel?.id`), or the resolved provider (`getProviderByName(providerId)`). It is a hard precondition gate before any model creation or streaming begins.
Source
Thrown at web-app/src/lib/custom-chat-transport.ts:1123
messages: UIMessage[]
abortSignal: AbortSignal | undefined
} & {
trigger: 'submit-message' | 'regenerate-message'
messageId: string | undefined
} & ChatRequestOptions
): Promise<ReadableStream<UIMessageChunk>> {
const threadId = this.threadId ?? options.chatId
const myGeneration = ++this.streamGeneration
useAppState.getState().setCurrentStreamThreadId(threadId)
// Capture the effective provider name early so the Anthropic serial
// tool-use repair later uses the same value that was used to create the
// model, even if the user switches provider mid-request.
const modelId = useModelProvider.getState().selectedModel?.id
const providerId = useModelProvider.getState().selectedProvider
const effectiveProviderName = providerId
const provider = useModelProvider.getState().getProviderByName(providerId)
if (!this.serviceHub || !modelId || !provider) {
throw new Error('ServiceHub not initialized or model/provider missing.')
}
this.lastUserMessage = extractLatestUserText(options.messages)
try {
const updatedProvider = useModelProvider
.getState()
.getProviderByName(providerId)
const inferenceParams = this.getActiveInferenceParams()
const selectedModel = useModelProvider.getState().selectedModel
const reasoningParams = buildLlamacppReasoningParams(
effectiveProviderName,
selectedModel?.settings?.reasoning?.controller_props?.value as
| 'auto'
| 'on'
| 'off'View on GitHub (pinned to fad3f12a14)
Solutions
- Ensure a provider and model are selected before enabling the send button.
- Verify ServiceHub is initialized (await its ready signal) before sendMessages can fire.
- Clear `selectedProvider` when a provider is deleted so the UI falls back to a valid one.
- Show a setup prompt instead of letting the send path run.
Example fix
// before
const provider = useModelProvider.getState().getProviderByName(providerId)
if (!this.serviceHub || !modelId || !provider) {
throw new Error('ServiceHub not initialized or model/provider missing.')
}
// after
const provider = useModelProvider.getState().getProviderByName(providerId)
if (!this.serviceHub) {
throw new Error('ServiceHub not initialized yet. Wait for startup to finish.')
}
if (!provider || !modelId) {
throw new Error('No model or provider selected. Choose one before sending.')
} Defensive patterns
Strategy: validation
Validate before calling
const { selectedModel, selectedProvider } = useModelProvider.getState()
const provider = useModelProvider.getState().getProviderByName(selectedProvider)
if (!this.serviceHub) {
toast.error('App still starting up', { description: 'Try again in a moment.' })
return
}
if (!selectedModel?.id || !provider) {
toast.error('No model selected', { description: 'Choose a provider and model first.' })
return
} Type guard
function hasSendPreconditions(hub: unknown, modelId: unknown, provider: unknown): boolean {
return !!hub && typeof modelId === 'string' && modelId.length > 0 && !!provider && typeof (provider as any).base_url === 'string'
} Try / catch
try {
if (!hasSendPreconditions(this.serviceHub, modelId, provider)) {
toast.error('Cannot send message', { description: 'ServiceHub, model, or provider not ready.' })
return
}
// proceed
} catch (error) {
console.error('sendMessages precondition failure:', error)
throw error
} Prevention
- Disable the send button until a provider + model are selected and ServiceHub is ready.
- Clear selectedProvider when its provider is deleted.
- Await ServiceHub initialization before allowing sends.
- Show a first-run setup flow so these are never null.
When it happens
Trigger: Sending a message before ServiceHub finished initializing; `selectedProvider` points to a provider name that no longer exists in the store (deleted/renamed); no model selected (`selectedModel` is null); providerId is undefined because the provider store was reset.
Common situations: Race where the user sends a message during app startup before ServiceHub is injected; the selected provider was removed by the user but the selected-provider pointer wasn't cleared; migrating provider configs left a dangling reference; first-run with no provider configured.
Related errors
- model-errors:createModelFailed
- ${friendly} (${requestUrlOf(input)})
- Model already loaded!!
- No active session found for model: ${modelId}
- Model ${modelId} does not exist
AI-assisted analysis of janhq/jan@fad3f12a14 (2026-08-12).
Data as JSON: /api/errors/10b49289fc7f1bbf.
Report an issue: GitHub.