chenhg5/cc-connect · error

invalid source session key: %w

Error message

invalid source session key: %w

What it means

relayContextForSourceSessionKey parses a source session key into platform name and chat ID to build a relay conversation key; if parseSessionKeyParts rejects the key, the error is wrapped as 'invalid source session key: %w'. Session keys must follow the platform:chatID structure the engine expects. A malformed key means the relay target cannot be resolved at all.

Source

Thrown at core/engine.go:15929

func (platformNameOnly) Stop() error                              { return nil }

func relayConversationKey(fromProject, platformName, chatID string) string {
	return "relay:" + fromProject + ":" + workspaceChannelKey(platformName, chatID)
}

func (e *Engine) platformForName(name string) Platform {
	for _, p := range e.platforms {
		if strings.EqualFold(p.Name(), name) {
			return p
		}
	}
	return platformNameOnly{name: name}
}

func (e *Engine) relayContextForSourceSessionKey(fromProject, sourceSessionKey string) (Agent, *SessionManager, string, error) {
	platformName, chatID, err := parseSessionKeyParts(sourceSessionKey)
	if err != nil {
		return nil, nil, "", fmt.Errorf("invalid source session key: %w", err)
	}

	relaySessionKey := relayConversationKey(fromProject, platformName, chatID)
	if !e.multiWorkspace || e.workspaceBindings == nil {
		return e.agent, e.sessions, relaySessionKey, nil
	}

	channelKey := workspaceChannelKey(platformName, chatID)
	workspace, _, err := e.resolveWorkspace(e.platformForName(platformName), chatID)
	if err != nil {
		return nil, nil, "", fmt.Errorf("resolve relay workspace: %w", err)
	}
	if workspace == "" {
		if b, _, usable := e.lookupEffectiveWorkspaceBinding(channelKey); b != nil && !usable {
			return nil, nil, "", fmt.Errorf("workspace binding unavailable for source channel %q", channelKey)
		}
		return nil, nil, "", fmt.Errorf("no workspace binding for source channel %q", channelKey)
	}

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Print/log the sourceSessionKey and compare it to keys emitted by the engine (platformName:chatID format)
  2. Fix the key in the config/automation that supplied it — use the session list command to copy a valid key
  3. If keys come from persisted state, check for a version upgrade that changed the key format and migrate
  4. Ensure no empty string is passed when a session key is required

Example fix

// before
agent, sessions, key, err := e.relayContextForSourceSessionKey(project, "12345678") // missing platform
// after
agent, sessions, key, err := e.relayContextForSourceSessionKey(project, "telegram:12345678")
Defensive patterns

Strategy: validation

Validate before calling

func validSessionKey(key string) bool {
    _, _, err := parseSessionKeyParts(key)
    return err == nil
}
// call before relayContextForSourceSessionKey

Try / catch

agent, sessions, key, err := e.relayContextForSourceSessionKey(project, srcKey)
if err != nil {
    var se *parseError
    if errors.As(err, &se) {
        slog.Error("bad session key in config", "key", srcKey)
    }
    return err
}

Prevention

When it happens

Trigger: Calling the relay path (e.g. /relay or cross-project message forwarding) with a sourceSessionKey string that does not contain the expected delimiter/parts — empty string, wrong number of segments, or a key produced by an older cc-connect version with a different format.

Common situations: Hardcoded or hand-edited session key in a cron/timer config; keys persisted by a previous version before a format change; passing a chat ID instead of a full session key; whitespace or typo in a configured key.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/da46d412b262c11c. Report an issue: GitHub.