{"record":{"id":"b492fd4d03acae5f","repo":"chenhg5/cc-connect","slug":"googlechat-missing-space-in-reply-context-b492fd","errorCode":null,"errorMessage":"googlechat: missing space in reply context","messagePattern":"googlechat: missing space in reply context","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/googlechat/streaming.go","lineNumber":31,"sourceCode":")\n\n// previewHandle points at the in-flight streaming-preview message so\n// UpdateMessage can patch it in place via spaces.messages.patch.\ntype previewHandle struct {\n\tname string // e.g. \"spaces/AAA/messages/MMM\"\n}\n\n// SendPreviewStart posts the initial streaming-preview message (threaded like a\n// normal reply) and returns a handle for subsequent edits. Implements\n// core.PreviewStarter; together with UpdateMessage it lights up the engine's\n// real-time streaming preview for Google Chat.\nfunc (p *Platform) SendPreviewStart(ctx context.Context, rctx any, content string) (any, error) {\n\trc, ok := rctx.(replyContext)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"googlechat: invalid reply context type %T\", rctx)\n\t}\n\tif rc.space == \"\" {\n\t\treturn nil, fmt.Errorf(\"googlechat: missing space in reply context\")\n\t}\n\turl, body, err := buildSendRequest(rc, content)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treq, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(body))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"googlechat: build request: %w\", err)\n\t}\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tresp, err := p.doRequest(req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"googlechat: send preview: %w\", err)\n\t}\n\tdefer func() {\n\t\tif err := resp.Body.Close(); err != nil {\n\t\t\tslog.Warn(\"googlechat: close preview response body\", \"error\", err)\n\t\t}","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/googlechat/streaming.go#L13-L49","documentation":"After the type assertion succeeds, SendPreviewStart still requires replyContext.space to be non-empty, because the preview message must be posted into a Chat space. An empty space fails fast with this message instead of issuing a doomed API call.","triggerScenarios":"A streaming preview is started for a conversation whose replyContext was built without a space name — e.g. DMs or webhook-sourced messages missing space metadata.","commonSituations":"Bot in chats where messages lack space.name; hand-constructed reply contexts omitting Space; upstream Chat API changes to message payloads.","solutions":["Populate replyContext.space from the incoming message's space resource name","Disable streaming preview for conversations without a space, or fall back to plain replies","Log the incoming message payload to confirm space metadata is present"],"exampleFix":"// before\nrc := replyContext{} // no space\np.SendPreviewStart(ctx, rc, content)\n// after\nrc := replyContext{Space: msg.GetSpace().GetName()}\nif rc.Space == \"\" { return errors.New(\"no space for preview\") }\np.SendPreviewStart(ctx, rc, content)","handlingStrategy":"validation","validationCode":"if rc, ok := rctx.(replyContext); !ok || rc.Space == \"\" { return errors.New(\"preview requires a google chat space\") }","typeGuard":"func canStartPreview(rctx any) bool { rc, ok := rctx.(replyContext); return ok && rc.Space != \"\" }","tryCatchPattern":"if _, err := p.SendPreviewStart(ctx, rctx, content); err != nil {\n    if strings.Contains(err.Error(), \"missing space\") { return fallbackToPlainReply(ctx, rctx, content) }\n    return err\n}","preventionTips":["Populate replyContext.space from incoming message metadata at receipt time","Disable streaming for spaceless conversations","Alert on incoming Chat messages lacking space.name"],"tags":["googlechat","streaming","validation"],"backgroundTag":"empty-required-field","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}