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

  1. Ensure a provider and model are selected before enabling the send button.
  2. Verify ServiceHub is initialized (await its ready signal) before sendMessages can fire.
  3. Clear `selectedProvider` when a provider is deleted so the UI falls back to a valid one.
  4. 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

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


AI-assisted analysis of janhq/jan@fad3f12a14 (2026-08-12). Data as JSON: /api/errors/10b49289fc7f1bbf. Report an issue: GitHub.