chenhg5/cc-connect · warning
message, tts_text, or attachment is required
Error message
message, tts_text, or attachment is required
What it means
The /send endpoint requires at least one of: message text, tts_text, or an attachment (images, files, audios, videos). A syntactically valid JSON body whose SendRequest has all of these empty is rejected with 400, because there is nothing to deliver to the agent session.
Source
Thrown at core/api.go:221
func (s *APIServer) handleSend(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "POST only", http.StatusMethodNotAllowed)
return
}
// Attachments travel base64-encoded inside the JSON body (~4/3 expansion)
// plus the request envelope, so size the reader to fit one max-size
// attachment with overhead to spare. The previous hard-coded 52 MB cap was
// smaller than a single 50 MB attachment after base64 encoding and would
// reject valid sends; deriving it from maxAttachmentBytes keeps the body
// limit in step with the configured attachment limit.
var req SendRequest
if err := json.NewDecoder(io.LimitReader(r.Body, s.sendBodyLimit())).Decode(&req); err != nil {
http.Error(w, "invalid JSON: "+err.Error(), http.StatusBadRequest)
return
}
if req.Message == "" && strings.TrimSpace(req.TTSText) == "" && len(req.Images) == 0 && len(req.Files) == 0 && len(req.Audios) == 0 && len(req.Videos) == 0 {
http.Error(w, "message, tts_text, or attachment is required", http.StatusBadRequest)
return
}
s.mu.RLock()
var engine *Engine
var ok bool
if req.Project != "" {
engine, ok = s.engines[req.Project]
} else if len(s.engines) == 1 {
// No project specified and only one engine: use it by default.
// Do NOT silently fall back when a non-empty project name is unknown —
// that misroutes the message to the wrong engine. Mirrors the resolve
// pattern in webhook.go and handleCronAdd.
for _, e := range s.engines {
engine = e
ok = true
}
}View on GitHub (pinned to 4000b2338a)
Solutions
- Include a non-empty field: `{"message":"hello"}` or `{"tts_text":"..."}` or at least one entry in images/files/audios/videos.
- Check the client isn't sending the text under a different key (the endpoint expects `message`, not `text` or `content`).
- Trim or reject whitespace-only messages on the caller side before sending.
- If the payload should have content, log the exact JSON body being posted — a failed template interpolation often yields empty strings.
Example fix
// before
{"message":"", "files":[]}
// after
{"message":"hello agent"} Defensive patterns
Strategy: validation
Validate before calling
if req.Message == "" && req.TTSText == "" && len(req.Images) == 0 &&
len(req.Files) == 0 && len(req.Audios) == 0 && len(req.Videos) == 0 {
return errors.New("nothing to send: set message, tts_text, or an attachment")
} Try / catch
if resp.StatusCode == 400 && strings.Contains(respBody, "message, tts_text, or attachment is required") {
// fix payload construction before retrying
} Prevention
- Validate the payload client-side before posting
- Use the exact field name `message` (not text/content)
- Guard templates against interpolating to empty strings
- Trim whitespace-only messages before sending
When it happens
Trigger: POSTing valid JSON like {} or {"message":""} to /send where message is empty/whitespace, tts_text is empty, and images/files/audios/videos arrays are all empty.
Common situations: Client bug sending an empty payload after stripping content, double-encoding so the text ends up in a wrong field (e.g. nested under data), whitespace-only messages that fail the implicit emptiness check, a template that failed to interpolate its placeholder.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- invalid JSON:
- usage endpoint returned status %d: %s
- reasonix: POST %s returned %d: %s
- gitee API returned HTTP %d
- http %d: %s
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/c27d077559f316a3.
Report an issue: GitHub.