{"record":{"id":"9af4887998f8f047","repo":"googleapis/mcp-toolbox","slug":"failed-to-add-document-w","errorCode":null,"errorMessage":"failed to add document: %w","messagePattern":"failed to add document: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sources/firestore/firestore.go","lineNumber":322,"sourceCode":"\t\t\tdocData[\"createTime\"] = snapshot.CreateTime\n\t\t\tdocData[\"updateTime\"] = snapshot.UpdateTime\n\t\t\tdocData[\"readTime\"] = snapshot.ReadTime\n\t\t}\n\n\t\tresults[i] = docData\n\t}\n\n\treturn results, nil\n}\n\nfunc (s *Source) AddDocuments(ctx context.Context, collectionPath string, documentData any, returnData bool) (map[string]any, error) {\n\t// Get the collection reference\n\tcollection := s.FirestoreClient().Collection(collectionPath)\n\n\t// Add the document to the collection\n\tdocRef, writeResult, err := collection.Add(ctx, documentData)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to add document: %w\", err)\n\t}\n\t// Build the response\n\tresponse := map[string]any{\n\t\t\"documentPath\": docRef.Path,\n\t\t\"createTime\":   writeResult.UpdateTime.Format(\"2006-01-02T15:04:05.999999999Z\"),\n\t}\n\t// Add document data if requested\n\tif returnData {\n\t\t// Fetch the updated document to return the current state\n\t\tsnapshot, err := docRef.Get(ctx)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to retrieve updated document: %w\", err)\n\t\t}\n\t\t// Convert the document data back to simple JSON format\n\t\tsimplifiedData := FirestoreValueToJSON(snapshot.Data())\n\t\tresponse[\"documentData\"] = simplifiedData\n\t}\n\treturn response, nil","sourceCodeStart":304,"sourceCodeEnd":340,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/sources/firestore/firestore.go#L304-L340","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check the wrapped cause; if 'permission denied', add roles/datastore.user to the service account.","Verify payload size < 1 MiB per document and move large blobs to Cloud Storage.","Ensure documentData contains only Firestore-compatible types.","If quota exceeded, request a quota increase or throttle writes with batching.","Retry on transient UNAVAILABLE with exponential backoff."],"exampleFix":"// before\nbig := map[string]any{\"blob\": string(make([]byte, 2<<20))}\n_, err := source.AddDocuments(ctx, \"docs\", big)\n// after\nbig := map[string]any{\"blobGcsUri\": \"gs://bucket/blob.bin\"}\n_, err := source.AddDocuments(ctx, \"docs\", big)","handlingStrategy":"validation","validationCode":"// Go\nfunc validateDocumentData(data map[string]any) error {\n    if len(data) == 0 {\n        return errors.New(\"document data must not be empty\")\n    }\n    b, err := json.Marshal(data)\n    if err != nil {\n        return fmt.Errorf(\"data contains unsupported types: %w\", err)\n    }\n    if len(b) > 1<<20 {\n        return fmt.Errorf(\"document size %d bytes exceeds 1 MiB limit\", len(b))\n    }\n    return nil\n}","typeGuard":"func isWritableValue(v any) bool {\n    switch v.(type) {\n    case string, bool, int, int64, float64, []any, map[string]any, nil, time.Time:\n        return true\n    default:\n        return false\n    }\n}","tryCatchPattern":"resp, err := source.AddDocuments(ctx, collection, data)\nif err != nil {\n    switch {\n    case strings.Contains(err.Error(), \"permission denied\"):\n        return fmt.Errorf(\"grant roles/datastore.user: %w\", err)\n    case strings.Contains(err.Error(), \"RESOURCE_EXHAUSTED\"):\n        return fmt.Errorf(\"quota exceeded, throttle writes: %w\", err)\n    default:\n        return fmt.Errorf(\"add document failed: %w\", err)\n    }\n}","preventionTips":["Check payload size against the 1 MiB document limit; offload blobs to Cloud Storage.","Only pass JSON-serializable, Firestore-compatible values.","Confirm service account write IAM before deployment.","Batch large write bursts to stay within quota."],"tags":["firestore","write","grpc","gcp"],"backgroundTag":"firestore-write-failed","analyzedSha":"8cc6e09de2ad7b8bffc77751799585a1401a48eb","analyzedAt":"2026-09-05T01:10:36.887Z","contentChangedAt":"2026-09-05T01:10:36.887Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}