{"record":{"id":"0996f71fd9a6c82b","repo":"vxcontrol/pentagi","slug":"failed-to-store-answer-for-question-w","errorCode":null,"errorMessage":"failed to store answer for question: %w","messagePattern":"failed to store answer for question: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/pkg/tools/search.go","lineNumber":295,"sourceCode":"\t\t\t\tlogger.WithError(err).Error(\"failed to load document\")\n\t\t\t\treturn \"\", fmt.Errorf(\"failed to load document: %w\", err)\n\t\t\t}\n\t\t\tfor i := range docs {\n\t\t\t\tif docs[i].Metadata == nil {\n\t\t\t\t\tdocs[i].Metadata = map[string]any{}\n\t\t\t\t}\n\t\t\t\tmaps.Copy(docs[i].Metadata, metadata)\n\t\t\t\tdocs[i].Metadata[\"part_size\"] = len(docs[i].PageContent)\n\t\t\t}\n\t\t\tids, err = s.store.AddDocuments(ctx, docs)\n\t\t\teventMetadata[\"ids\"] = ids\n\t\t\tif err != nil {\n\t\t\t\tobservation.Event(append(opts,\n\t\t\t\t\tlangfuse.WithEventStatus(err.Error()),\n\t\t\t\t\tlangfuse.WithEventLevel(langfuse.ObservationLevelError),\n\t\t\t\t)...)\n\t\t\t\tlogger.WithError(err).Error(\"failed to store answer for question\")\n\t\t\t\treturn \"\", fmt.Errorf(\"failed to store answer for question: %w\", err)\n\t\t\t}\n\t\t} else {\n\t\t\t// Slow path: Answer field exceeds embedding limit.\n\t\t\t// PageContent is just the answer text, so overhead = 0.\n\t\t\tembeddingText := truncateForEmbedding(anonymizedAnswer, s.maxEmbeddingBytes)\n\n\t\t\tid, err := storeDocumentWithEmbeddingLimit(ctx, s.db, s.embedder,\n\t\t\t\tembeddingText, anonymizedAnswer, metadata)\n\t\t\tif err != nil {\n\t\t\t\tobservation.Event(append(opts,\n\t\t\t\t\tlangfuse.WithEventStatus(err.Error()),\n\t\t\t\t\tlangfuse.WithEventLevel(langfuse.ObservationLevelError),\n\t\t\t\t)...)\n\t\t\t\tlogger.WithError(err).Error(\"failed to store answer with embedding limit\")\n\t\t\t\treturn \"\", fmt.Errorf(\"failed to store answer for question: %w\", err)\n\t\t\t}\n\t\t\tids = []string{id}\n\t\t\tdocs = []schema.Document{","sourceCodeStart":277,"sourceCodeEnd":313,"githubUrl":"https://github.com/vxcontrol/pentagi/blob/ea665308baaff015b226f308438a68d929d0f29b/backend/pkg/tools/search.go#L277-L313","documentation":"On the 'fast path' of store-answer (where the answer fits within the embedding byte limit), the vector store rejected the add/update of the Q&A document. The error wraps the underlying store/embedding failure and is also reported to the Langfuse observation with error level.","triggerScenarios":"`store answer` invoked with an anonymized answer at or under `maxEmbeddingBytes`; the subsequent `store.AddDocument`-style call fails due to DB errors, embedding API errors, or invalid metadata types.","commonSituations":"Embedding provider quota exhausted or key invalid; transient Postgres disconnects; metadata containing non-scalar values the store rejects; concurrent migrations locking the documents table.","solutions":["Read the wrapped root error to distinguish embedding-provider vs database failure.","Validate embedding provider credentials/quota in env config.","Keep metadata values scalar (string/number/bool) to avoid store-side rejection.","Retry transient DB failures with backoff; the operation is otherwise idempotent per question."],"exampleFix":"// before\nerr := store.AddDocument(ctx, doc) // no retry on transient failure\n// after\nerr := retry.Do(ctx, 3, time.Second, func() error { return store.AddDocument(ctx, doc) })","handlingStrategy":"retry","validationCode":"if !embedProviderHealthy(ctx) {\n    return errors.New(\"embedding provider unavailable, skipping store answer\")\n}\nfor k, v := range metadata {\n    switch v.(type) {\n    case string, int, int64, float64, bool, nil:\n    default:\n        return fmt.Errorf(\"metadata %q has non-scalar type %T\", k, v)\n    }\n}","typeGuard":null,"tryCatchPattern":"err := storeAnswerFastPath(ctx, action)\nif err != nil && strings.Contains(err.Error(), \"failed to store answer for question\") {\n    if isRetryable(errors.Unwrap(err)) {\n        return backoffRetry(ctx, 3, time.Second, storeAnswerFastPath, action)\n    }\n    observation.Event(langfuse.WithEventStatus(err.Error()))\n    return err\n}","preventionTips":["Monitor embedding provider quota/keys before storing answers.","Retry transient DB/network failures with exponential backoff.","Keep metadata scalar-only to avoid store-side validation rejections.","Alert on Langfuse error-level events for the store-answer tool."],"tags":["pgvector","embedding","store-answer","database"],"backgroundTag":"vector-store-write-failed","analyzedSha":"ea665308baaff015b226f308438a68d929d0f29b","analyzedAt":"2026-09-01T14:16:31.421Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}