{"record":{"id":"f0691e8f09fae953","repo":"moeru-ai/airi","slug":"artistry-provider-is-disabled","errorCode":null,"errorMessage":"Artistry provider is disabled.","messagePattern":"Artistry provider is disabled\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"apps/stage-tamagotchi/src/main/services/airi/widgets/artistry-bridge.ts","lineNumber":150,"sourceCode":"  const fingerprint = JSON.stringify({\n    p: params.prompt,\n    m: params.model,\n    pr: params.provider,\n    o: params.options,\n    ih: imageHash,\n    gh: globalsHash, // Include globals hash (Issue #39)\n  })\n\n  if (pendingHeadlessRequests.has(fingerprint)) {\n    log.log(`[Headless] Deduplicating identical request: ${params.prompt.slice(0, 30)}...`)\n    return pendingHeadlessRequests.get(fingerprint)!\n  }\n\n  const executionPromise = (async () => {\n    const requestedProvider = (params.provider || artistryConfig.get()?.artistryProvider || DEFAULT_ARTISTRY_PROVIDER).trim().toLowerCase()\n    if (requestedProvider === 'none') {\n      log.log('[Headless] Provider is \\'none\\'. Bypassing generation.')\n      throw new Error('Artistry provider is disabled.')\n    }\n\n    const provider = artistryProviders.get(requestedProvider)\n    if (!provider) {\n      log.error(`[Headless] Provider '${requestedProvider}' not found in registry.`)\n      throw new Error(`Provider '${requestedProvider}' not found.`)\n    }\n\n    // Initialize the provider\n    if (provider.initialize && activeGlobals) {\n      log.log(`[Headless] Initializing provider ${requestedProvider} with globals...`)\n      await provider.initialize(activeGlobals)\n    }\n\n    log.log(`[Headless] Globals keys: ${Object.keys(activeGlobals || {}).join(', ')}`)\n    if (activeGlobals?.image)\n      log.log(`[Headless] Source image length: ${activeGlobals.image.length}`)\n","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/moeru-ai/airi/blob/27111382b4a79a7e983289d6e983a06af185ed0f/apps/stage-tamagotchi/src/main/services/airi/widgets/artistry-bridge.ts#L132-L168","documentation":"Thrown by generateHeadless when the resolved artistry provider name equals 'none'. Resolution order is params.provider, then the configured artistryProvider, then DEFAULT_ARTISTRY_PROVIDER; if the effective value is 'none', generation is intentionally bypassed and this error surfaces the deliberate disablement.","triggerScenarios":"The artistry config sets artistryProvider to 'none' (disabling image generation), or a caller explicitly passes provider: 'none', and then code still attempts generateHeadless expecting an image.","commonSituations":"A user turned off the artistry provider in settings but a widget/feature still calls generateHeadless; the config default resolved to 'none' after a config reset; a feature was not updated to handle the disabled-provider case.","solutions":["Set artistryProvider to a valid provider name (comfyui, replicate, nanobanana) in the artistry config.","Before calling generateHeadless, check the resolved provider and skip/handle the 'none' case gracefully in the caller.","If 'none' is a legitimate 'feature off' state, treat this error as a signal to fall back to a placeholder or no-op rather than surfacing it to the user."],"exampleFix":"// before\nconst result = await generateHeadless({ prompt, provider: resolvedProvider })\n\n// after\nif (resolvedProvider === 'none') {\n  return { imageUrl: undefined, error: 'Artistry is disabled' }\n}\nconst result = await generateHeadless({ prompt, provider: resolvedProvider })","handlingStrategy":"validation","validationCode":"const provider = (params.provider || artistryConfig.get()?.artistryProvider || DEFAULT_ARTISTRY_PROVIDER).trim().toLowerCase()\nif (provider === 'none') {\n  return { imageUrl: undefined, error: 'Artistry is disabled' }\n}\nreturn await generateHeadless(params)","typeGuard":null,"tryCatchPattern":"try {\n  return await generateHeadless(params)\n} catch (e) {\n  if (/provider is disabled/i.test(errorMessageFrom(e) ?? '')) {\n    return { imageUrl: undefined, error: 'Artistry disabled' }\n  }\n  throw e\n}","preventionTips":["Treat provider === 'none' as a feature-off state in the UI and hide/disable generation affordances.","Resolve the effective provider once and branch before calling generateHeadless.","Document 'none' as a valid config value that disables generation."],"tags":["artistry","config","feature-flag","providers"],"backgroundTag":null,"analyzedSha":"27111382b4a79a7e983289d6e983a06af185ed0f","analyzedAt":"2026-08-12T18:33:34.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}