{"record":{"id":"b035057a9fba03b0","repo":"chenhg5/cc-connect","slug":"message-tts-text-or-attachment-is-required","errorCode":null,"errorMessage":"message, tts text, or attachment is required","messagePattern":"message, tts text, or attachment is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/cc-connect/send.go","lineNumber":212,"sourceCode":"\t\treturn req, \"\", err\n\t}\n\tvideoFiles, err := loadTypedFileAttachments(videoPaths, \"video\", maxAtt)\n\tif err != nil {\n\t\treturn req, \"\", err\n\t}\n\treq.Images = images\n\t// Keep audio / video clips on dedicated fields. Routing them through\n\t// req.Files would force the engine to dispatch them via FileSender —\n\t// that loses the native voice-bubble / video-bubble path on platforms\n\t// that implement AudioSender / VideoSender (e.g. Feishu's ffmpeg\n\t// transcode for mp3 → opus). See cc-connect internal task\n\t// t-20260615-cqjbk1.\n\treq.Files = files\n\treq.Audios = audioFiles\n\treq.Videos = videoFiles\n\n\tif req.Message == \"\" && req.TTSText == \"\" && len(req.Images) == 0 && len(req.Files) == 0 && len(req.Audios) == 0 && len(req.Videos) == 0 {\n\t\treturn req, \"\", fmt.Errorf(\"message, tts text, or attachment is required\")\n\t}\n\n\treturn req, dataDir, nil\n}\n\nfunc loadImageAttachments(paths []string, maxSize int64) ([]core.ImageAttachment, error) {\n\timages := make([]core.ImageAttachment, 0, len(paths))\n\tfor _, path := range paths {\n\t\tdata, fileName, mimeType, err := readAttachment(path, maxSize)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tif !strings.HasPrefix(mimeType, \"image/\") {\n\t\t\treturn nil, fmt.Errorf(\"%s is not an image (detected mime: %s)\", path, mimeType)\n\t\t}\n\t\timages = append(images, core.ImageAttachment{MimeType: mimeType, Data: data, FileName: fileName})\n\t}\n\treturn images, nil","sourceCodeStart":194,"sourceCodeEnd":230,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/cmd/cc-connect/send.go#L194-L230","documentation":"parseSendArgs rejects requests that carry no content at all: message, TTS text, and all attachment lists (images, files, audios, videos) empty. This final validation prevents sending a pointless/empty message to the platform. It fires even when valid flags like --work-dir were given, since they carry no user content.","triggerScenarios":"`cc-connect send --work-dir /p` with no --message, --tts, or attachment flags; `--stdin` used but stdin was empty; attachment variables empty so no --image/--file flags were added.","commonSituations":"Automated scripts where the message variable is empty and no attachments resolved; piping an empty string via --stdin; forgetting that flags like --data-dir or --at-users alone do not satisfy the content requirement.","solutions":["Provide content: add `--message \"...\"`, `--tts \"...\"`, or at least one --image/--file/--audio/--video.","If piping via --stdin, verify the producer emits non-empty output (whitespace-only stdin is trimmed to empty).","In scripts, guard: `[ -n \"$MSG\" ] || cc-connect send --image \"$IMG\" ...`.","Check the config/source that was supposed to supply the message text."],"exampleFix":"// before\ncc-connect send --work-dir /proj\n// after\ncc-connect send --work-dir /proj --message \"run the tests\"","handlingStrategy":"validation","validationCode":"MSG=${MSG:-}\nif [ -z \"$MSG\" ] && [ -z \"$IMG\" ] && [ -z \"$FILE\" ]; then\n  echo \"nothing to send\"; exit 1\nfi\ncmd=(cc-connect send)\n[ -n \"$MSG\" ] && cmd+=(--message \"$MSG\")\n[ -n \"$IMG\" ] && cmd+=(--image \"$IMG\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always supply at least one of --message, --tts, or an attachment flag.","Check for empty message variables in scripts.","Remember --stdin with empty input counts as no content.","Flags like --work-dir/--at-users do not satisfy the content requirement."],"tags":["cli","validation","empty-message"],"backgroundTag":"missing-required-argument","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}