chenhg5/cc-connect · error
relay: target engine %q not found (is the project running?)
Error message
relay: target engine %q not found (is the project running?)
What it means
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.
Source
Thrown at core/relay.go:231
targetEngine := rm.engines[req.To]
sourceEngine := rm.engines[req.From]
visibility := rm.visibility
rm.mu.RUnlock()
if binding == nil {
return nil, fmt.Errorf("relay: no binding for this chat. Use /bind <project> first")
}
if _, ok := binding.Bots[req.To]; !ok {
var bound []string
for proj := range binding.Bots {
if proj != req.From {
bound = append(bound, proj)
}
}
return nil, fmt.Errorf("relay: project %q is not bound in this chat. Available targets: %s (use the exact name)", req.To, strings.Join(bound, ", "))
}
if targetEngine == nil {
return nil, fmt.Errorf("relay: target engine %q not found (is the project running?)", req.To)
}
fromName := req.From
if binding.Bots[req.From] != "" {
fromName = binding.Bots[req.From]
}
toName := req.To
if binding.Bots[req.To] != "" {
toName = binding.Bots[req.To]
}
// Post the forwarded message to the group chat for visibility. The
// default target is "<platform>:<chatID>:relay"; platforms that
// understand thread / topic semantics can override this by
// implementing core.RelayGroupVisibilityTarget on their Platform impl.
groupSessionKey := rm.resolveGroupVisibilityKey(platform, chatID, req.SessionKey, sourceEngine)
if sourceEngine != nil && visibility != RelayVisibilityNone {
label := relayVisibilityRequestLabel(visibility, fromName, toName, req.Message)View on GitHub (pinned to 4000b2338a)
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
Example fix
// before: engine never started
rm.RegisterEngine("backend", nil) // or never called
rm.Send(ctx, core.RelayRequest{To: "backend", ...}) // -> not found
// after: create and start the engine, then register
eng := core.NewEngine(cfg); go eng.Start(ctx); rm.RegisterEngine("backend", eng) Defensive patterns
Strategy: validation
Validate before calling
func targetRunning(rm *core.RelayManager, name string) bool {
rm.RLock(); defer rm.RUnlock()
return rm.Engines()[name] != nil
}
// check before Send; if false, tell the user to start the target project Type guard
if eng := rm.LookupEngine(req.To); eng == nil { return fmt.Errorf("project %s is not running", req.To) } Try / catch
resp, err := rm.Send(ctx, req)
if err != nil {
if strings.Contains(err.Error(), "target engine") && strings.Contains(err.Error(), "not found") {
reply("Target project is not running. Start it and retry.")
return
}
return err
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- attachment send is disabled by config
- %s
- session process is not running
- write stdin: %w
- process tree (pid %d) still alive after SIGKILL retries: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/b23298c30ad5a30a.
Report an issue: GitHub.