{"record":{"id":"78203e5b73defee5","repo":"chenhg5/cc-connect","slug":"max-edit-message-http-d-s","errorCode":null,"errorMessage":"max: edit message: HTTP %d: %s","messagePattern":"max: edit message: HTTP (.+?): (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/max/max.go","lineNumber":524,"sourceCode":"\t}\n\treq, err := http.NewRequestWithContext(ctx, http.MethodPut, p.apiBase+\"/messages\", bytes.NewReader(data))\n\tif err != nil {\n\t\treturn err\n\t}\n\tp.setAuth(req)\n\tq := req.URL.Query()\n\tq.Set(\"message_id\", rctx.messageID)\n\treq.URL.RawQuery = q.Encode()\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\n\tresp, err := p.client.Do(req)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"max: edit message: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\tif resp.StatusCode != http.StatusOK {\n\t\trespBody, _ := io.ReadAll(io.LimitReader(resp.Body, 512))\n\t\treturn fmt.Errorf(\"max: edit message: HTTP %d: %s\", resp.StatusCode, respBody)\n\t}\n\treturn nil\n}\n\n// uploadAttachment performs the two-step MAX upload: request an upload URL from\n// /uploads?type=<kind>, then POST the binary as multipart/form-data field \"data\"\n// to that URL. Returns the token to embed in a subsequent /messages attachment.\nfunc (p *Platform) uploadAttachment(ctx context.Context, kind string, data []byte, filename string) (string, error) {\n\tif len(data) == 0 {\n\t\treturn \"\", fmt.Errorf(\"empty attachment data\")\n\t}\n\t// Use a 5-minute context AND a dedicated http.Client with a matching Timeout.\n\t// p.client has a 35 s Timeout which fires independently of the context deadline\n\t// and would abort large CDN uploads before the context expires.\n\tuploadCtx, cancel := context.WithTimeout(ctx, attachmentUploadTO)\n\tdefer cancel()\n\n\turlReq, err := http.NewRequestWithContext(uploadCtx, http.MethodPost, p.apiBase+\"/uploads\", nil)","sourceCodeStart":506,"sourceCodeEnd":542,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/max/max.go#L506-L542","documentation":"This error is returned by Platform.UpdateMessage when the MAX Bot API responds to a message-edit request with a non-200 HTTP status. The library wraps the status code and up to 512 bytes of the response body so the caller can see exactly why the edit was rejected. It means the API call itself succeeded at the transport level but the server refused the edit.","triggerScenarios":"Calling UpdateMessage (or the max.EditMessage path) when the MAX API returns e.g. 400 (malformed message ID/text), 401/403 (bad or expired bot token), 404 (message ID no longer exists or belongs to another chat), or 429/5xx from the server.","commonSituations":"Editing a message after the chat/message was deleted; using a stale or revoked bot token; passing a message ID obtained from a different chat; MAX API rate limiting during heavy streaming edits; transient MAX server errors (5xx).","solutions":["Log respBody and status from the error to identify the exact API rejection reason","Verify the bot token is valid and has permission for the target chat","Confirm the message ID exists and was not deleted before editing","If status is 429, add backoff/retry; if 5xx, retry with exponential backoff","Update the MAX Bot API client assumptions if the API contract changed"],"exampleFix":"// before\nif err := p.UpdateMessage(ctx, chatID, msgID, newText); err != nil { return err }\n// after\nif err := p.UpdateMessage(ctx, chatID, msgID, newText); err != nil {\n    var httpErr interface{ Error() string }\n    _ = httpErr\n    slog.Warn(\"max: edit failed, falling back to new message\", \"err\", err)\n    _, err = p.Reply(ctx, chatID, newText)\n    return err\n}","handlingStrategy":"try-catch","validationCode":"if msgID == \"\" || newText == \"\" { return errors.New(\"max: message id and text required before edit\") }","typeGuard":null,"tryCatchPattern":"if err := p.UpdateMessage(ctx, chatID, msgID, text); err != nil {\n    if strings.Contains(err.Error(), \"HTTP 429\") || strings.Contains(err.Error(), \"HTTP 5\") {\n        // retry with backoff\n    } else {\n        return fmt.Errorf(\"edit message: %w\", err)\n    }\n}","preventionTips":["Check message existence before editing","Refresh bot tokens before expiry","Distinguish retryable (429/5xx) from permanent (4xx) statuses in error handling","Log the response body embedded in the error for diagnosis"],"tags":["http","api","max","edit-message"],"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"}