{"record":{"id":"a6d9d43edb25891a","repo":"chenhg5/cc-connect","slug":"message-or-attachment-is-required","errorCode":null,"errorMessage":"message or attachment is required","messagePattern":"message or attachment is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/engine.go","lineNumber":11192,"sourceCode":"\nfunc (e *Engine) SendToSessionWithOptions(sessionKey, message string, images []ImageAttachment, files []FileAttachment, opts SendOptions) error {\n\tif strings.TrimSpace(opts.WorkDir) != \"\" {\n\t\tworkDir, useWorkDirSession, err := e.resolveSendWorkDir(opts.WorkDir)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif useWorkDirSession {\n\t\t\treturn e.SendToSessionInWorkDir(sessionKey, message, images, files, workDir, opts.AtUsers, opts.AtAll)\n\t\t}\n\t}\n\n\tstate, p, replyCtx, err := e.resolveOutboundSessionTarget(sessionKey, len(images) > 0 || len(files) > 0)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif message == \"\" && len(images) == 0 && len(files) == 0 {\n\t\treturn fmt.Errorf(\"message or attachment is required\")\n\t}\n\tif (len(images) > 0 || len(files) > 0) && !e.attachmentSendEnabled {\n\t\treturn ErrAttachmentSendDisabled\n\t}\n\n\tvar imageSender ImageSender\n\tif len(images) > 0 {\n\t\tvar ok bool\n\t\timageSender, ok = p.(ImageSender)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"platform %s: %w\", p.Name(), ErrNotSupported)\n\t\t}\n\t}\n\n\tvar fileSender FileSender\n\tif len(files) > 0 {\n\t\tvar ok bool\n\t\tfileSender, ok = p.(FileSender)","sourceCodeStart":11174,"sourceCodeEnd":11210,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/core/engine.go#L11174-L11210","documentation":"This error is returned by the Engine's session-send path when a send request is issued with an empty message body and no image or file attachments. The engine refuses to dispatch a completely empty outgoing message because platforms require at least one of text, images, or files to render a reply.","triggerScenarios":"Calling the engine's send-to-session API (the one at core/engine.go that calls resolveOutboundSessionTarget) with message=\"\", images=nil, files=nil — e.g. building the message from a variable that turned out empty, or trimming whitespace from the text before calling.","commonSituations":"Automation scripts that pass a shell variable which is empty; templates where all fields were optional and none were filled; callers that intended to send only an attachment but the attachment slice failed to populate.","solutions":["Ensure at least one of message text, images, or files is non-empty before calling the send API","Trim-check the message: if strings.TrimSpace(message)==\"\" && len(images)==0 && len(files)==0, abort or substitute placeholder text","If the intent was attachment-only, verify the attachment list was actually populated (file read succeeded)"],"exampleFix":"// before\nengine.SendToSession(key, msg, nil, nil, \"\", nil, false)\n// after\nif strings.TrimSpace(msg) == \"\" && len(imgs) == 0 && len(files) == 0 {\n    return fmt.Errorf(\"nothing to send\")\n}\nengine.SendToSession(key, msg, imgs, files, \"\", nil, false)","handlingStrategy":"validation","validationCode":"if strings.TrimSpace(message) == \"\" && len(images) == 0 && len(files) == 0 {\n    return fmt.Errorf(\"refusing to send: empty message and no attachments\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate payload completeness at the call-site boundary before invoking engine send APIs","Never build send payloads from unvalidated dynamic strings","Unit-test send helpers with an empty-payload case"],"tags":["go","validation","empty-message"],"backgroundTag":"empty-required-field","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}