vxcontrol/pentagi · error

failed to load document: %w

Error message

failed to load document: %w

What it means

The vector store failed to load documents for the store-answer flow — i.e. the embedding/retrieval backend (pgvector) returned an error while `s.store.Load(ctx, ...)` ran, after the answer was anonymized and the document was built. The underlying DB/embedding error is wrapped for diagnosis.

Source

Thrown at backend/pkg/tools/search.go:278

			metadata["subtask_id"] = *s.subtaskID
		}

		var (
			docs []schema.Document
			ids  []string
			err  error
		)

		if len(anonymizedAnswer) <= s.maxEmbeddingBytes || s.embedder == nil {
			// Fast path: answer fits within the embedding limit.
			docs, err = documentloaders.NewText(strings.NewReader(anonymizedAnswer)).Load(ctx)
			if err != nil {
				observation.Event(append(opts,
					langfuse.WithEventStatus(err.Error()),
					langfuse.WithEventLevel(langfuse.ObservationLevelError),
				)...)
				logger.WithError(err).Error("failed to load document")
				return "", fmt.Errorf("failed to load document: %w", err)
			}
			for i := range docs {
				if docs[i].Metadata == nil {
					docs[i].Metadata = map[string]any{}
				}
				maps.Copy(docs[i].Metadata, metadata)
				docs[i].Metadata["part_size"] = len(docs[i].PageContent)
			}
			ids, err = s.store.AddDocuments(ctx, docs)
			eventMetadata["ids"] = ids
			if err != nil {
				observation.Event(append(opts,
					langfuse.WithEventStatus(err.Error()),
					langfuse.WithEventLevel(langfuse.ObservationLevelError),
				)...)
				logger.WithError(err).Error("failed to store answer for question")
				return "", fmt.Errorf("failed to store answer for question: %w", err)
			}

View on GitHub (pinned to ea665308ba)

Solutions

  1. Check the wrapped `%w` error and backend logs for the root cause (DB vs embedding).
  2. Verify Postgres/pgvector availability and run pending migrations.
  3. Confirm the embedding model's dimensions match the vector column definition.
  4. Retry with a fresh context if the cause was a deadline/cancellation.
  5. Check Langfuse event status recorded alongside the error for the upstream message.

Example fix

// before
ctx := context.Background() // unbounded; timeouts kill long embeddings
// after
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
Defensive patterns

Strategy: try-catch

Validate before calling

if err := pgPing(ctx, dsn); err != nil {
    return fmt.Errorf("pgvector unreachable before store answer: %w", err)
}
if embDim := embeddingDims(ctx, model); embDim != expectedDim {
    return fmt.Errorf("embedding dims %d != column dims %d", embDim, expectedDim)
}

Try / catch

out, err := searchTool.Handle(ctx, tools.StoreAnswerToolName, args)
if err != nil {
    if strings.Contains(err.Error(), "failed to load document") {
        if isTransientDBError(errors.Unwrap(err)) {
            return retryWithBackoff(ctx, 3, func() error { return storeAnswer(ctx, args) })
        }
        return fmt.Errorf("vector store unavailable, answer not saved: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: During `StoreAnswerToolName` handling, the call that loads/stores the document into pgvector returns an error — DB connection failure, pgvector extension missing, embedding provider error, dimension mismatch, or context canceled/deadline exceeded.

Common situations: Postgres restarted or connection pool exhausted; pgvector index missing after migration failure; embedding model changed so vector dimensions no longer match the column; long answers causing embedding timeouts.

Related errors


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/6179685602bfee16. Report an issue: GitHub.