{"record":{"id":"300339b4c1d2a82b","repo":"linshenkx/prompt-optimizer","slug":"no-valid-messages-after-processing","errorCode":null,"errorMessage":"No valid messages after processing","messagePattern":"No valid messages after processing","errorType":"validation","errorClass":"TestError","httpStatus":null,"severity":"error","filePath":"packages/core/src/services/prompt/service.ts","lineNumber":1129,"sourceCode":"      }\n      if (!request.messages || request.messages.length === 0) {\n        throw new TestError(\"\", \"\", \"At least one message is required\");\n      }\n\n      // 验证模型存在\n      const modelConfig = await this.modelManager.getModel(request.modelKey);\n      if (!modelConfig) {\n        throw new TestError(\"\", \"\", \"Model not found\");\n      }\n\n      // 处理会话消息：替换变量\n      const processedMessages = TemplateProcessor.processConversationMessages(\n        request.messages,\n        request.variables,\n      );\n\n      if (processedMessages.length === 0) {\n        throw new TestError(\"\", \"\", \"No valid messages after processing\");\n      }\n\n      // 使用流式发送，根据是否有工具选择不同的方法\n      if (request.tools && request.tools.length > 0) {\n        // 🆕 使用支持工具的流式发送\n        await this.llmService.sendMessageStreamWithTools(\n          processedMessages,\n          request.modelKey,\n          request.tools,\n          {\n            onToken: callbacks.onToken,\n            onReasoningToken: callbacks.onReasoningToken,\n            onToolCall: callbacks.onToolCall, // 🆕 传递工具调用回调\n            onComplete: async (response) => {\n              if (response) {\n                console.log(\n                  \"[PromptService] Custom conversation test with tools completed successfully\",\n                );","sourceCodeStart":1111,"sourceCodeEnd":1147,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/core/src/services/prompt/service.ts#L1111-L1147","documentation":"Thrown after TemplateProcessor.processConversationMessages returns an empty array — i.e., every message was filtered out during variable substitution/processing. The service deliberately refuses to send an empty conversation to the LLM.","triggerScenarios":"Passing messages whose content is empty after variable substitution, or messages of types that TemplateProcessor drops, so processedMessages.length === 0. Also happens if request.messages itself is empty (the earlier guard only checks a raw emptiness path).","commonSituations":"Template references variables not supplied, causing content to resolve to empty string; all messages are system/whitespace-only; overly aggressive message filtering in a custom TemplateProcessor.","solutions":["Inspect request.messages and request.variables: ensure at least one message yields non-empty content after substitution","Provide all required variables in request.variables","Debug by calling TemplateProcessor.processConversationMessages directly and logging the result to see which messages are dropped"],"exampleFix":"// before\nawait svc.testCustomConversationStream({ modelKey, messages: [{ role: 'user', content: '{{query}}' }], variables: {} });\n\n// after\nconst vars = { query: 'hello' };\nconst processed = TemplateProcessor.processConversationMessages(msgs, vars);\nif (processed.length === 0) throw new Error('All messages empty after substitution');\nawait svc.testCustomConversationStream({ modelKey, messages: msgs, variables: vars });","handlingStrategy":"validation","validationCode":"const processed = TemplateProcessor.processConversationMessages(req.messages, req.variables ?? {});\nif (processed.length === 0) {\n  throw new Error('No messages survive template processing — check variables and message content');\n}\nawait svc.testCustomConversationStream(req);","typeGuard":"const hasContent = (msgs: Msg[]): msgs is [Msg, ...Msg[]] =>\n  TemplateProcessor.processConversationMessages(msgs, vars).length > 0;","tryCatchPattern":"try { await svc.testCustomConversationStream(req); } catch (e) { if (e instanceof TestError && /No valid messages/.test(e.message)) { /* fix variables, show editor hint */ } else throw e; }","preventionTips":["Default missing variables to a placeholder instead of empty string in templates","Live-preview rendered message content in the prompt editor","Require at least one non-empty user message in the UI before enabling test"],"tags":["template","validation","prompt-testing"],"backgroundTag":"empty-request-validation","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}