{"record":{"id":"b23298c30ad5a30a","repo":"chenhg5/cc-connect","slug":"relay-target-engine-q-not-found-is-the-project","errorCode":null,"errorMessage":"relay: target engine %q not found (is the project running?)","messagePattern":"relay: target engine %q not found \\(is the project running\\?\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/relay.go","lineNumber":231,"sourceCode":"\ttargetEngine := rm.engines[req.To]\n\tsourceEngine := rm.engines[req.From]\n\tvisibility := rm.visibility\n\trm.mu.RUnlock()\n\n\tif binding == nil {\n\t\treturn nil, fmt.Errorf(\"relay: no binding for this chat. Use /bind <project> first\")\n\t}\n\tif _, ok := binding.Bots[req.To]; !ok {\n\t\tvar bound []string\n\t\tfor proj := range binding.Bots {\n\t\t\tif proj != req.From {\n\t\t\t\tbound = append(bound, proj)\n\t\t\t}\n\t\t}\n\t\treturn nil, fmt.Errorf(\"relay: project %q is not bound in this chat. Available targets: %s (use the exact name)\", req.To, strings.Join(bound, \", \"))\n\t}\n\tif targetEngine == nil {\n\t\treturn nil, fmt.Errorf(\"relay: target engine %q not found (is the project running?)\", req.To)\n\t}\n\n\tfromName := req.From\n\tif binding.Bots[req.From] != \"\" {\n\t\tfromName = binding.Bots[req.From]\n\t}\n\ttoName := req.To\n\tif binding.Bots[req.To] != \"\" {\n\t\ttoName = binding.Bots[req.To]\n\t}\n\n\t// Post the forwarded message to the group chat for visibility.  The\n\t// default target is \"<platform>:<chatID>:relay\"; platforms that\n\t// understand thread / topic semantics can override this by\n\t// implementing core.RelayGroupVisibilityTarget on their Platform impl.\n\tgroupSessionKey := rm.resolveGroupVisibilityKey(platform, chatID, req.SessionKey, sourceEngine)\n\tif sourceEngine != nil && visibility != RelayVisibilityNone {\n\t\tlabel := relayVisibilityRequestLabel(visibility, fromName, toName, req.Message)","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/core/relay.go#L213-L249","documentation":"Thrown by RelayManager.Send when req.To is bound in the chat but rm.engines has no engine registered under that project name — i.e. the target project's Engine isn't running or wasn't registered with the RelayManager. Binding and engine registration are separate concerns; this error catches the gap.","triggerScenarios":"The target project's cc-connect process is stopped or crashed; the engine was never started/registered under the exact name used in the binding; a typo in the project's config name means the engine registered under a different key than the one bound.","commonSituations":"Second project not started yet (single cc-connect instance instead of per-project daemons); target engine crashed and wasn't restarted; project renamed in one place (config or /bind) but not the other.","solutions":["Start the target project's cc-connect instance/engine so it registers with the RelayManager","Confirm the engine registration name exactly equals the bound project name","Check the target process's logs for startup failure and fix the underlying cause","After restarting, re-issue the relay request"],"exampleFix":"// before: engine never started\nrm.RegisterEngine(\"backend\", nil) // or never called\nrm.Send(ctx, core.RelayRequest{To: \"backend\", ...}) // -> not found\n// after: create and start the engine, then register\neng := core.NewEngine(cfg); go eng.Start(ctx); rm.RegisterEngine(\"backend\", eng)","handlingStrategy":"validation","validationCode":"func targetRunning(rm *core.RelayManager, name string) bool {\n\trm.RLock(); defer rm.RUnlock()\n\treturn rm.Engines()[name] != nil\n}\n// check before Send; if false, tell the user to start the target project","typeGuard":"if eng := rm.LookupEngine(req.To); eng == nil { return fmt.Errorf(\"project %s is not running\", req.To) }","tryCatchPattern":"resp, err := rm.Send(ctx, req)\nif err != nil {\n\tif strings.Contains(err.Error(), \"target engine\") && strings.Contains(err.Error(), \"not found\") {\n\t\treply(\"Target project is not running. Start it and retry.\")\n\t\treturn\n\t}\n\treturn err\n}","preventionTips":["Keep engine registration names identical to the names used in /bind","Add health checks/restarts (systemd Restart=always) so engines stay registered","Monitor engine liveness and alert when a bound project's engine is down"],"tags":["relay","engine","process-lifecycle"],"backgroundTag":"resource-not-found","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"}