{"record":{"id":"51c3766d4e11b7f8","repo":"chenhg5/cc-connect","slug":"project-is-required-multiple-projects-configured-51c376","errorCode":null,"errorMessage":"project is required (multiple projects configured)","messagePattern":"project is required \\(multiple projects configured\\)","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"core/api.go","lineNumber":244,"sourceCode":"\tvar engine *Engine\n\tvar ok bool\n\tif req.Project != \"\" {\n\t\tengine, ok = s.engines[req.Project]\n\t} else if len(s.engines) == 1 {\n\t\t// No project specified and only one engine: use it by default.\n\t\t// Do NOT silently fall back when a non-empty project name is unknown —\n\t\t// that misroutes the message to the wrong engine. Mirrors the resolve\n\t\t// pattern in webhook.go and handleCronAdd.\n\t\tfor _, e := range s.engines {\n\t\t\tengine = e\n\t\t\tok = true\n\t\t}\n\t}\n\ts.mu.RUnlock()\n\n\tif !ok {\n\t\tif req.Project == \"\" {\n\t\t\thttp.Error(w, \"project is required (multiple projects configured)\", http.StatusBadRequest)\n\t\t\treturn\n\t\t}\n\t\thttp.Error(w, fmt.Sprintf(\"project %q not found\", req.Project), http.StatusNotFound)\n\t\treturn\n\t}\n\n\tworkDir := req.WorkDir\n\tif workDir == \"\" {\n\t\tworkDir = req.CWD\n\t}\n\tif req.Message != \"\" || len(req.Images) > 0 || len(req.Files) > 0 {\n\t\tif err := engine.SendToSessionWithOptions(req.SessionKey, req.Message, req.Images, req.Files, SendOptions{WorkDir: workDir, AtUsers: req.AtUsers, AtAll: req.AtAll}); err != nil {\n\t\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\n\t\t\treturn\n\t\t}\n\t}\n\n\tif len(req.Audios) > 0 {","sourceCodeStart":226,"sourceCodeEnd":262,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/core/api.go#L226-L262","documentation":"handleSend on the HTTP API received no project name while more than one engine/project is configured, so it cannot decide which project's engine should deliver the message. This is a deliberate refusal to guess rather than a routing bug.","triggerScenarios":"Thrown at core/api.go:244 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Include the project field in the /api/send request body naming the target project","Reduce to a single configured project if no routing is needed"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}