{"record":{"id":"da46d412b262c11c","repo":"chenhg5/cc-connect","slug":"invalid-source-session-key-w","errorCode":null,"errorMessage":"invalid source session key: %w","messagePattern":"invalid source session key: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/engine.go","lineNumber":15929,"sourceCode":"func (platformNameOnly) Stop() error                              { return nil }\n\nfunc relayConversationKey(fromProject, platformName, chatID string) string {\n\treturn \"relay:\" + fromProject + \":\" + workspaceChannelKey(platformName, chatID)\n}\n\nfunc (e *Engine) platformForName(name string) Platform {\n\tfor _, p := range e.platforms {\n\t\tif strings.EqualFold(p.Name(), name) {\n\t\t\treturn p\n\t\t}\n\t}\n\treturn platformNameOnly{name: name}\n}\n\nfunc (e *Engine) relayContextForSourceSessionKey(fromProject, sourceSessionKey string) (Agent, *SessionManager, string, error) {\n\tplatformName, chatID, err := parseSessionKeyParts(sourceSessionKey)\n\tif err != nil {\n\t\treturn nil, nil, \"\", fmt.Errorf(\"invalid source session key: %w\", err)\n\t}\n\n\trelaySessionKey := relayConversationKey(fromProject, platformName, chatID)\n\tif !e.multiWorkspace || e.workspaceBindings == nil {\n\t\treturn e.agent, e.sessions, relaySessionKey, nil\n\t}\n\n\tchannelKey := workspaceChannelKey(platformName, chatID)\n\tworkspace, _, err := e.resolveWorkspace(e.platformForName(platformName), chatID)\n\tif err != nil {\n\t\treturn nil, nil, \"\", fmt.Errorf(\"resolve relay workspace: %w\", err)\n\t}\n\tif workspace == \"\" {\n\t\tif b, _, usable := e.lookupEffectiveWorkspaceBinding(channelKey); b != nil && !usable {\n\t\t\treturn nil, nil, \"\", fmt.Errorf(\"workspace binding unavailable for source channel %q\", channelKey)\n\t\t}\n\t\treturn nil, nil, \"\", fmt.Errorf(\"no workspace binding for source channel %q\", channelKey)\n\t}","sourceCodeStart":15911,"sourceCodeEnd":15947,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/core/engine.go#L15911-L15947","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Print/log the sourceSessionKey and compare it to keys emitted by the engine (platformName:chatID format)","Fix the key in the config/automation that supplied it — use the session list command to copy a valid key","If keys come from persisted state, check for a version upgrade that changed the key format and migrate","Ensure no empty string is passed when a session key is required"],"exampleFix":"// before\nagent, sessions, key, err := e.relayContextForSourceSessionKey(project, \"12345678\") // missing platform\n// after\nagent, sessions, key, err := e.relayContextForSourceSessionKey(project, \"telegram:12345678\")","handlingStrategy":"validation","validationCode":"func validSessionKey(key string) bool {\n    _, _, err := parseSessionKeyParts(key)\n    return err == nil\n}\n// call before relayContextForSourceSessionKey","typeGuard":null,"tryCatchPattern":"agent, sessions, key, err := e.relayContextForSourceSessionKey(project, srcKey)\nif err != nil {\n    var se *parseError\n    if errors.As(err, &se) {\n        slog.Error(\"bad session key in config\", \"key\", srcKey)\n    }\n    return err\n}","preventionTips":["Always copy session keys from engine output, never hand-type them","Validate configured session keys at config-load time","Pin config format to the cc-connect version and migrate keys on upgrade","Reject empty session keys early with a clear message"],"tags":["session-key","parsing","relay","go"],"backgroundTag":"invalid-argument-format","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"}