{"record":{"id":"99f2220c1fac20d4","repo":"chenhg5/cc-connect","slug":"max-chat-action-s-status-d","errorCode":null,"errorMessage":"max: chat action %s: status %d","messagePattern":"max: chat action (.+?): status (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"platform/max/max.go","lineNumber":716,"sourceCode":"\t}\n\turl := p.apiBase + \"/chats/\" + chatID + \"/actions\"\n\treq, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(body))\n\tif err != nil {\n\t\treturn err\n\t}\n\tp.setAuth(req)\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\tresp, err := p.client.Do(req)\n\tif err != nil {\n\t\tslog.Debug(\"max: chat action failed\", \"chat\", chatID, \"action\", action, \"err\", err)\n\t\treturn err\n\t}\n\tdefer resp.Body.Close()\n\tif resp.StatusCode >= 300 {\n\t\trespBody, _ := io.ReadAll(io.LimitReader(resp.Body, 256))\n\t\tslog.Debug(\"max: chat action non-2xx\",\n\t\t\t\"chat\", chatID, \"action\", action, \"status\", resp.StatusCode, \"body\", string(respBody))\n\t\treturn fmt.Errorf(\"max: chat action %s: status %d\", action, resp.StatusCode)\n\t}\n\treturn nil\n}\n\n// FormattingInstructions implements core.FormattingInstructionProvider.\n// The engine appends this to the agent system prompt so Claude uses only\n// MAX-supported markdown syntax.\nfunc (p *Platform) FormattingInstructions() string {\n\treturn `Formatting rules for MAX messenger:\n- **bold** and _italic_ are supported\n- Inline code: ` + \"`code`\" + ` and fenced code blocks (` + \"```\" + `) are supported\n- Bullet lists with - or * are supported as plain text\n- Do NOT use headers (# ## ###)\n- Do NOT use horizontal rules (--- or ***)\n- Do NOT use tables\n- Do NOT use HTML tags\nKeep responses concise and use plain text where possible.`\n}","sourceCodeStart":698,"sourceCodeEnd":734,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/max/max.go#L698-L734","documentation":"sendChatAction posts a presence action (typing_on / mark_seen) to MAX at /chats/{id}/actions; this error is returned when MAX answers with a non-2xx status. It is deliberately best-effort: StartTyping and the re-arm goroutine discard it (errors are only logged at debug level), so it normally surfaces only in tests or when calling sendChatAction directly. It indicates the typing/seen indicator request was rejected by MAX.","triggerScenarios":"StartTyping (or the anonymous ticker callback) firing when the chatID is invalid/deleted, the bot lacks permission for that chat, the action string is not accepted by the API version, or MAX is returning 4xx/5xx (rate limit 429, auth 401, server 500).","commonSituations":"Typing indicator re-armed after the chat was deleted or the bot was removed; stale chat IDs from restored sessions; expired bot tokens; MAX rate-limiting rapid re-arming of typing_on; calling TestUploadKindPropagation-style tests without a reachable/authorized API.","solutions":["Enable debug logging and read the logged respBody (slog \"max: chat action non-2xx\") — it shows MAX's specific reason (401 auth, 403 permission, 404 chat, 429 rate limit).","Refresh the bot token if 401; verify the bot is still a member of the chat if 403/404.","For 429, lengthen typingInterval so the re-arm ticker sends fewer requests.","Since the return value is ignored in StartTyping, treat this as non-fatal for the message flow; only fix it if typing indicators matter to your users.","Verify the chatID embedded in the session key is current — reconstruct from a fresh incoming message if it is stale."],"exampleFix":"// before (error silently discarded)\n_ = p.sendChatAction(tickCtx, rctx.chatID, \"typing_on\")\n// after: surface and adapt to rate limits\nif err := p.sendChatAction(tickCtx, rctx.chatID, \"typing_on\"); err != nil {\n\tslog.Warn(\"max: typing indicator failed\", \"chat\", rctx.chatID, \"err\", err)\n}","handlingStrategy":"try-catch","validationCode":"// Validate inputs and session freshness before re-arming typing\nfunc canSendChatAction(chatID string) bool {\n\treturn chatID != \"\"\n}","typeGuard":null,"tryCatchPattern":"if err := p.sendChatAction(ctx, chatID, \"typing_on\"); err != nil {\n\t// best-effort: log at debug, never fail the message flow\n\tslog.Debug(\"max: chat action failed\", \"chat\", chatID, \"err\", err)\n}","preventionTips":["Always treat chat-action errors as non-fatal; typing indicators are cosmetic.","Check the debug log body for 401/403/404/429 and fix the underlying cause (token, membership, rate).","Space typing_on re-arms at least a few seconds apart to avoid 429s.","Reconstruct reply contexts from fresh incoming messages so chatIDs stay valid."],"tags":["http","typing-indicator","max","best-effort"],"backgroundTag":"http-error-response","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"}