api-core 2.35.0 breaks Firestore "(default)" database id — every call fails with "400 Invalid database id %28default%29"
**Package:** google-api-core 2.35.0 (affects google-cloud-firestore; likely any client passing resource ids containing RFC 3986 reserved characters)
### Environment
- Python 3.13 (also reproduced on the `python:3.13-slim` container image)
- google-cloud-firestore 2.28.1 and 2.29.0 (both affected)
- google-api-core **2.35.0** (released 2026-08-24 ~21:55 UTC)
- Transport: gRPC (the default; the error surfaces via `google.api_core.grpc_helpers.error_remapped_callable`)
### Steps to reproduce
```python
from google.cloud import firestore
db = firestore.Client(project="<any-project>", database="(default)")
db.collection("any_collection").document("any_id").get()
```
### Actual behavior
Every RPC fails immediately:
```
google.api_core.exceptions.InvalidArgument: 400 Invalid database id %28default%29
```
Note the server echoes the **percent-encoded** database id — the client is sending `%28default%29` where the backend expects the literal `(default)`.
### Expected behavior
The default-database id `(default)` reaches the backend unencoded, as it did in every release through 2.34.0.
### Bisection (only google-api-core varied; same code and credentials throughout)
| google-api-core | google-cloud-firestore | Result |
|---|---|---|
| 2.30.3 | 2.27.0 | ✅ works |
| 2.34.0 | 2.29.0 | ✅ works |
| **2.35.0** | 2.28.1 | ❌ `400 Invalid database id %28default%29` |
| **2.35.0** | 2.29.0 | ❌ same error |
### The regression is specific to ids with reserved characters
On 2.35.0, a database id **without** special characters still reaches the backend intact — pointing the client at a non-existent named database returns a clean `404 The database no-such-db does not exist for project ...`, with the id echoed verbatim and un-encoded. Only the parenthesized `(default)` id gets corrupted.
### Suspected change
The 2.35.0 changelog entry *"fix(api_core): improve rest path validation"* ([#17753](https://github.com/googleapis/google-cloud-python/issues/17753)) is the prime suspect given the bisection window (2.34.0 → 2.35.0). Parentheses are outside the RFC 3986 unreserved set, so a stricter encoding pass "correctly" percent-encodes them — but the Firestore backend validates the database id literally and rejects the encoded form. Since the failure occurs over gRPC, the encoding appears to be applied to the request path / routing metadata shared by both transports, not just REST URLs.
### Impact
Any workload using the default Firestore database (i.e. most Firestore users) that resolves dependencies without an upper bound on google-api-core loses all Firestore access the first time it rebuilds/redeploys. We were hit in a deployed environment within minutes of the release. Current mitigation: pin `google-api-core<2.35.0`.
4 条评论