googleapis/mcp-toolbox · error

failed to add document: %w

Error message

failed to add document: %w

What it means

Thrown by Source.AddDocuments when collection.Add(ctx, documentData) fails to create a new auto-ID document in Firestore. The client error is wrapped verbatim so the underlying cause (quota, permission, write size, connection) remains inspectable. It means the document was not created and no write result exists.

Source

Thrown at internal/sources/firestore/firestore.go:322

			docData["createTime"] = snapshot.CreateTime
			docData["updateTime"] = snapshot.UpdateTime
			docData["readTime"] = snapshot.ReadTime
		}

		results[i] = docData
	}

	return results, nil
}

func (s *Source) AddDocuments(ctx context.Context, collectionPath string, documentData any, returnData bool) (map[string]any, error) {
	// Get the collection reference
	collection := s.FirestoreClient().Collection(collectionPath)

	// Add the document to the collection
	docRef, writeResult, err := collection.Add(ctx, documentData)
	if err != nil {
		return nil, fmt.Errorf("failed to add document: %w", err)
	}
	// Build the response
	response := map[string]any{
		"documentPath": docRef.Path,
		"createTime":   writeResult.UpdateTime.Format("2006-01-02T15:04:05.999999999Z"),
	}
	// Add document data if requested
	if returnData {
		// Fetch the updated document to return the current state
		snapshot, err := docRef.Get(ctx)
		if err != nil {
			return nil, fmt.Errorf("failed to retrieve updated document: %w", err)
		}
		// Convert the document data back to simple JSON format
		simplifiedData := FirestoreValueToJSON(snapshot.Data())
		response["documentData"] = simplifiedData
	}
	return response, nil

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Check the wrapped cause; if 'permission denied', add roles/datastore.user to the service account.
  2. Verify payload size < 1 MiB per document and move large blobs to Cloud Storage.
  3. Ensure documentData contains only Firestore-compatible types.
  4. If quota exceeded, request a quota increase or throttle writes with batching.
  5. Retry on transient UNAVAILABLE with exponential backoff.

Example fix

// before
big := map[string]any{"blob": string(make([]byte, 2<<20))}
_, err := source.AddDocuments(ctx, "docs", big)
// after
big := map[string]any{"blobGcsUri": "gs://bucket/blob.bin"}
_, err := source.AddDocuments(ctx, "docs", big)
Defensive patterns

Strategy: validation

Validate before calling

// Go
func validateDocumentData(data map[string]any) error {
    if len(data) == 0 {
        return errors.New("document data must not be empty")
    }
    b, err := json.Marshal(data)
    if err != nil {
        return fmt.Errorf("data contains unsupported types: %w", err)
    }
    if len(b) > 1<<20 {
        return fmt.Errorf("document size %d bytes exceeds 1 MiB limit", len(b))
    }
    return nil
}

Type guard

func isWritableValue(v any) bool {
    switch v.(type) {
    case string, bool, int, int64, float64, []any, map[string]any, nil, time.Time:
        return true
    default:
        return false
    }
}

Try / catch

resp, err := source.AddDocuments(ctx, collection, data)
if err != nil {
    switch {
    case strings.Contains(err.Error(), "permission denied"):
        return fmt.Errorf("grant roles/datastore.user: %w", err)
    case strings.Contains(err.Error(), "RESOURCE_EXHAUSTED"):
        return fmt.Errorf("quota exceeded, throttle writes: %w", err)
    default:
        return fmt.Errorf("add document failed: %w", err)
    }
}

Prevention

When it happens

Trigger: Calling AddDocuments when the service account lacks write permission on the collection, the document payload exceeds the 1 MiB Firestore document limit, contains unsupported value types or an empty/invalid map, or the backend is unreachable/quota-exceeded.

Common situations: Posting documents larger than 1 MiB (often base64 blobs), missing roles/datastore.user after a service account rotation, exceeding write quotas in a burst, writing while pointed at an emulator with a mismatched project id.

Related errors


AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05). Data as JSON: /api/errors/9af4887998f8f047. Report an issue: GitHub.