{"record":{"id":"41b661f63a3f8583","repo":"moeru-ai/airi","slug":"prompt-is-required-for-image-journal-create","errorCode":null,"errorMessage":"prompt is required for image_journal.create","messagePattern":"prompt is required for image_journal\\.create","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/stage-tamagotchi/src/renderer/stores/tools/builtin/image-journal.ts","lineNumber":74,"sourceCode":"    mode: {\n      type: ['string', 'null'],\n      enum: ['inline', 'widget', 'bg', 'bg_widget', null],\n      description: 'Display mode: \"inline\" (in chat), \"widget\" (overlay), \"bg\" (environment), or \"bg_widget\" (both). Defaults to character preference.',\n    },\n  },\n  required: [\n    'action',\n    'prompt',\n    'title',\n    'query',\n    'mode',\n  ],\n  additionalProperties: false,\n} satisfies JsonSchema\n\nasync function executeCreateImageJournalEntry(params: { prompt?: string, title?: string, mode?: 'inline' | 'widget' | 'bg' | 'bg_widget' }) {\n  if (!params.prompt?.trim())\n    throw new Error('prompt is required for image_journal.create')\n\n  const backgroundStore = useBackgroundStore()\n  const cardStore = useAiriCardStore()\n  const activeCard = cardStore.activeCard\n  const globalArtistryConfig = getArtistryConfig()\n\n  const airiExt = activeCard?.extensions?.airi\n  const cardArtistry = airiExt?.modules?.artistry\n  const artistryConfig = {\n    provider: cardArtistry?.provider || globalArtistryConfig.provider,\n    model: cardArtistry?.model || globalArtistryConfig.model,\n    promptPrefix: cardArtistry?.promptPrefix || globalArtistryConfig.promptPrefix,\n    options: cardArtistry?.options || globalArtistryConfig.options,\n    globals: globalArtistryConfig.globals,\n  }\n\n  const title = params.title || `Generation ${new Date().toLocaleString()}`\n","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/moeru-ai/airi/blob/27111382b4a79a7e983289d6e983a06af185ed0f/apps/stage-tamagotchi/src/renderer/stores/tools/builtin/image-journal.ts#L56-L92","documentation":"Thrown by executeCreateImageJournalEntry when params.prompt is missing or whitespace-only after trim. The image_journal.create tool's JSON schema lists 'prompt' as required, but this runtime guard enforces it before any artistry call. The tool cannot proceed without a prompt to drive image generation.","triggerScenarios":"The model/tool-caller invoked image_journal.create with an empty or omitted prompt; the prompt argument was passed as whitespace; schema validation upstream was bypassed.","commonSituations":"LLM emitted the tool call with an empty prompt string; prompt field omitted from the tool-call arguments JSON; UI/test harness called the executor directly with no prompt.","solutions":["Ensure the tool-calling LLM always supplies a non-empty prompt argument.","Add schema-level enforcement (the schema already requires 'prompt') so invalid calls are rejected before the executor.","Surface a user-facing 'prompt is required' message and re-prompt the LLM.","If invoking manually, pass a non-empty prompt string."],"exampleFix":"// before\nexecuteCreateImageJournalEntry({ prompt: '   ' })\n\n// after\nexecuteCreateImageJournalEntry({ prompt: 'a calm sunset over the sea' })","handlingStrategy":"validation","validationCode":"function hasNonEmptyPrompt(params: { prompt?: string }): boolean {\n  return typeof params.prompt === 'string' && params.prompt.trim().length > 0\n}","typeGuard":"function isValidImageJournalPrompt(params: unknown): params is { prompt: string } {\n  return typeof params === 'object' && params !== null\n    && typeof (params as any).prompt === 'string'\n    && (params as any).prompt.trim().length > 0\n}","tryCatchPattern":null,"preventionTips":["Enforce the JSON schema 'required' before dispatching the tool call.","Strip empty prompt tool calls at the tool-router layer.","Re-prompt the LLM with the error when it omits the prompt."],"tags":["tool","image-journal","validation","artistry","llm-tool-call"],"backgroundTag":null,"analyzedSha":"27111382b4a79a7e983289d6e983a06af185ed0f","analyzedAt":"2026-08-12T18:33:34.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}