{"record":{"id":"633798e6eea259bd","repo":"Tencent/WeKnora","slug":"zhipu-response-exceeds-d-bytes","errorCode":null,"errorMessage":"Zhipu response exceeds %d bytes","messagePattern":"Zhipu response exceeds (.+?) bytes","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/infrastructure/web_search/zhipu.go","lineNumber":223,"sourceCode":"\t\ttime.RFC3339Nano,\n\t\t\"2006-01-02 15:04:05\",\n\t\t\"2006-01-02 15:04\",\n\t\t\"2006-01-02\",\n\t} {\n\t\tif parsed, err := time.Parse(layout, value); err == nil {\n\t\t\treturn parsed, true\n\t\t}\n\t}\n\treturn time.Time{}, false\n}\n\nfunc readZhipuResponseBody(reader io.Reader) ([]byte, error) {\n\tbody, err := io.ReadAll(io.LimitReader(reader, maxZhipuResponseBytes+1))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to read Zhipu response: %w\", err)\n\t}\n\tif len(body) > maxZhipuResponseBytes {\n\t\treturn nil, fmt.Errorf(\"Zhipu response exceeds %d bytes\", maxZhipuResponseBytes)\n\t}\n\treturn body, nil\n}\n\nfunc zhipuHTTPError(statusCode int, body []byte) error {\n\tvar response zhipuSearchResponse\n\tif err := json.Unmarshal(body, &response); err == nil && (response.Error.Code != \"\" || response.Error.Message != \"\") {\n\t\treturn fmt.Errorf(\"Zhipu API returned status %d (%s): %s\", statusCode, response.Error.Code, response.Error.Message)\n\t}\n\tdetail := strings.TrimSpace(string(body))\n\tif len(detail) > 4096 {\n\t\tdetail = detail[:4096]\n\t}\n\tif detail == \"\" {\n\t\treturn fmt.Errorf(\"Zhipu API returned status %d\", statusCode)\n\t}\n\treturn fmt.Errorf(\"Zhipu API returned status %d: %s\", statusCode, detail)\n}","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/infrastructure/web_search/zhipu.go#L205-L241","documentation":"The provider caps Zhipu response bodies at maxZhipuResponseBytes; it reads one extra byte via io.LimitReader and rejects any body exceeding the cap. This protects against unbounded memory consumption from a misbehaving or hostile endpoint.","triggerScenarios":"Calling Search() when Zhipu (or an intercepting proxy) returns a response body larger than maxZhipuResponseBytes.","commonSituations":"A proxy returning a huge error page; extremely large search result sets; a misconfigured endpoint echoing oversized payloads.","solutions":["Reduce maxResults / narrow the query so the response stays under the cap","Raise maxZhipuResponseBytes if legitimate payloads exceed it","Verify no proxy is inflating responses with extra content","Handle the error explicitly instead of treating it as transient"],"exampleFix":"// before\nresults, err := provider.Search(ctx, bigQuery) // huge result set\n// after\nctx = context.WithValue(ctx, key, opts)\nresults, err := provider.Search(ctx, query, WithMaxResults(10)) // keep payload small","handlingStrategy":"validation","validationCode":"if maxResults > 50 { return errors.New(\"reduce maxResults to stay under zhipu response byte cap\") }","typeGuard":"func isSizeLimitError(err error) bool { return strings.Contains(err.Error(), \"response exceeds\") }","tryCatchPattern":"results, err := provider.Search(ctx, q)\nif err != nil && strings.Contains(err.Error(), \"response exceeds\") {\n    return provider.Search(ctx, q, WithMaxResults(maxResults/2))\n}","preventionTips":["Keep maxResults modest so payloads stay under the byte cap","Do not blindly raise the cap — it exists to bound memory","Check for proxies appending/bloating response bodies","Handle size-limit errors distinctly from transient errors"],"tags":["limits","memory-safety","zhipu","web-search"],"backgroundTag":"response-body-too-large","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}