{"record":{"id":"f28ad574b03a93db","repo":"siyuan-note/siyuan","slug":"rerank-returned-d-indices-for-d-documents","errorCode":null,"errorMessage":"rerank returned %d indices for %d documents","messagePattern":"rerank returned (.+?) indices for (.+?) documents","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/util/openai.go","lineNumber":745,"sourceCode":"func truncateRerankDocument(document string) string {\n\trunes := []rune(document)\n\tif len(runes) > rerankDocTextMaxRunes {\n\t\treturn string(runes[:rerankDocTextMaxRunes])\n\t}\n\treturn document\n}\n\n// TestRerankModel 测试重排模型可用性，用极简 query+documents 发一次重排请求验证连通性与鉴权。\n// 返回值：matched 表示是否连通成功，err 为请求错误（鉴权失败、网络异常、模型不存在等，原样返回便于调用方展示原因）。\nfunc TestRerankModel(options RerankOptions) (matched bool, err error) {\n\tdocuments := []string{\"a\", \"b\"}\n\toptions.TopN = len(documents)\n\tindices, _, err := Rerank(\"1\", documents, options)\n\tif nil != err {\n\t\treturn\n\t}\n\tif len(indices) != len(documents) {\n\t\terr = fmt.Errorf(\"rerank returned %d indices for %d documents\", len(indices), len(documents))\n\t\treturn\n\t}\n\tseen := make(map[int]bool, len(indices))\n\tfor _, index := range indices {\n\t\tif seen[index] {\n\t\t\terr = fmt.Errorf(\"rerank returned duplicate index %d\", index)\n\t\t\treturn\n\t\t}\n\t\tseen[index] = true\n\t}\n\tmatched = true\n\treturn\n}\n\n// PrepareModelImage 校验并按需缩放图片，尽量保留多模态模型支持的原始格式和图片质量。\nfunc PrepareModelImage(data []byte, maxBytes, maxPixels, maxEdge int) (PreparedImage, error) {\n\tif len(data) == 0 {\n\t\treturn PreparedImage{}, errors.New(\"image data is empty\")","sourceCodeStart":727,"sourceCodeEnd":763,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/util/openai.go#L727-L763","documentation":"After a successful Rerank call, the caller validates that the number of returned indices equals the number of submitted documents and that every index maps 1:1 to a document. This error fires when the provider returned fewer or more indices than documents, so the rerank result cannot be trusted to reorder the original list. (The DECLARED/USED metadata in the error record points at app/electron/accessibility.js and is unrelated boilerplate; the authoritative location is the SOURCE region in kernel/util/openai.go.)","triggerScenarios":"Calling Rerank with N documents while the provider returns an index list of length != N — e.g. the provider silently drops documents, TopN is applied server-side, or the response truncates results.","commonSituations":"Provider that supports TopN/cutoff semantics differing from SiYuan's expectation; extremely large document batches where the provider truncates; a misbehaving or non-conformant rerank service.","solutions":["Compare the returned count to the submitted count logged in the error and check whether the provider applies TopN server-side","Reduce batch size and retry with fewer documents to rule out provider-side truncation","Verify provider docs: it must return one result per query-document pair for rerank calls","If the provider legitimately supports TopN, handle partial results at the call site instead of expecting 1:1"],"exampleFix":"// before: assumes 1:1 without controlling TopN\noptions.TopN = len(documents)\nindices, _, err := Rerank(\"1\", documents, options)\n// after: retry once with a smaller batch if the counts disagree\nif len(indices) != len(documents) {\n    options.TopN = len(documents)\n    indices, _, err = Rerank(\"1\", documents[:len(documents)/2], options)\n}","handlingStrategy":"validation","validationCode":"if len(docs) == 0 || docs.length > providerMaxBatch { chunk(docs, providerMaxBatch) }","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"indices for \") {\n    // counts diverged: fall back to original order\n    return docs\n}","preventionTips":["Keep batches within the provider's documented max documents per request","Never assume server-side TopN behavior; pass TopN explicitly and verify counts","Log submitted count alongside returned count for every rerank call"],"tags":["rerank","validation","ai-provider"],"backgroundTag":"shape-mismatch","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}