{"record":{"id":"7f091934c2b4eeb9","repo":"vxcontrol/pentagi","slug":"knowledge-similarity-search-user-d-w","errorCode":null,"errorMessage":"knowledge: similarity search (user %d): %w","messagePattern":"knowledge: similarity search \\(user (.+?)\\): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/database/knowledge/knowledge.go","lineNumber":398,"sourceCode":"\n\ttype searchRow struct {\n\t\tID        string\n\t\tDocument  string\n\t\tCmetadata sql.NullString\n\t\tScore     float64\n\t}\n\n\tvar rawRows []searchRow\n\n\tif userID > 0 {\n\t\trows, err := ks.db.SearchUserKnowledgeDocuments(ctx, database.SearchUserKnowledgeDocumentsParams{\n\t\t\tEmbedding:   vecLiteral,\n\t\t\tUserID:      nsOf(strconv.FormatInt(userID, 10)),\n\t\t\tMaxDistance: maxDist,\n\t\t\tLim:         int32(limit), //nolint:gosec\n\t\t})\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"knowledge: similarity search (user %d): %w\", userID, err)\n\t\t}\n\t\trawRows = make([]searchRow, len(rows))\n\t\tfor i, r := range rows {\n\t\t\trawRows[i] = searchRow{r.ID, r.Document, r.Cmetadata, r.Score}\n\t\t}\n\t} else {\n\t\trows, err := ks.db.SearchKnowledgeDocuments(ctx, database.SearchKnowledgeDocumentsParams{\n\t\t\tEmbedding:   vecLiteral,\n\t\t\tMaxDistance: maxDist,\n\t\t\tLim:         int32(limit), //nolint:gosec\n\t\t})\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"knowledge: similarity search (admin): %w\", err)\n\t\t}\n\t\trawRows = make([]searchRow, len(rows))\n\t\tfor i, r := range rows {\n\t\t\trawRows[i] = searchRow{r.ID, r.Document, r.Cmetadata, r.Score}\n\t\t}","sourceCodeStart":380,"sourceCodeEnd":416,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/database/knowledge/knowledge.go#L380-L416","documentation":"The user-scoped branch of doSearch runs SearchUserKnowledgeDocuments, a pgvector cosine-distance query filtered by user namespace. Any SQL execution error is wrapped as 'knowledge: similarity search (user <id>)'.","triggerScenarios":"Calling SearchUserDocuments when the vector column dimension mismatches the embedding model output, the pgvector extension is missing, limit is invalid, or the DB connection fails.","commonSituations":"Switching embedding models so stored vectors have a different dimension than vecLiteral (pgvector dimension mismatch error); fresh DB without migrations; connection pool exhaustion under load.","solutions":["Read the wrapped cause: 'vectors have different dimensions' means re-embed stored data or align the embedding model with the column dimension.","Run goose migrations to create/upgrade pgvector tables and extension.","Check PostgreSQL health and connection limits if the error is connection-related.","Validate the limit parameter if it triggers a query error."],"exampleFix":"// before\nLim: int32(limit), //nolint:gosec\n// after\nif limit <= 0 || limit > 1000 {\n    limit = defaultSearchLimit\n}\n// then: Lim: int32(limit),","handlingStrategy":"validation","validationCode":"if limit <= 0 {\n    limit = defaultSearchLimit\n}\nif strings.TrimSpace(query) == \"\" {\n    return errors.New(\"query must not be empty\")\n}","typeGuard":"func isDimensionMismatch(err error) bool {\n    return strings.Contains(err.Error(), \"different dimensions\") || strings.Contains(err.Error(), \"does not match\")\n}","tryCatchPattern":"docs, err := store.SearchUserDocuments(ctx, userID, query, filter, limit)\nif err != nil {\n    if isDimensionMismatch(err) {\n        // re-embed corpus or fix model config before retrying\n    }\n    return err\n}","preventionTips":["Keep the embedding model fixed for the lifetime of the vector column; version vector data.","Run pgvector migrations before deploying code that queries vectors.","Clamp user-supplied limit values server-side.","Monitor pgvector query latency and error rates."],"tags":["database","pgvector","sql"],"backgroundTag":"vector-dimension-mismatch","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}