Bug
In clients/new-js/packages/chromadb/src/chroma-client.ts, the CloudClient._path() method has the same TOCTOU race as the old client's init() (fixed in #7487).
Affected code (~line 191)
public async _path(): Promise<{ tenant: string; database: string }> {
if (!this._tenant || !this._database) { // ← checked before await
const { tenant, databases } = await this.getUserIdentity(); // ← suspends here
this._tenant = tenant; // ← set after resume
...
}
return { tenant: this._tenant, database: this._database };
}
When two operations (e.g. two simultaneous collection queries) call _path() before _tenant/_database are populated:
- Both callers see
!this._tenant → both enter the block
- Both
await getUserIdentity() → two concurrent auth calls
- Both write
this._tenant = tenant → last writer wins (no conflict here, but unnecessary double auth round-trip)
- If
getUserIdentity() returns different values across calls (e.g. due to token rotation), the final _tenant is non-deterministic
Suggested fix
Same lazy-promise pattern used to fix init():
private _pathPromise: Promise<{ tenant: string; database: string }> | undefined;
public async _path(): Promise<{ tenant: string; database: string }> {
if (!this._pathPromise) {
this._pathPromise = (async () => {
const { tenant, databases } = await this.getUserIdentity();
this._tenant = tenant;
// ... rest of setup
return { tenant: this._tenant, database: this._database };
})();
}
return this._pathPromise;
}
This ensures all concurrent callers await the same in-flight resolution.
Related
Bug
In
clients/new-js/packages/chromadb/src/chroma-client.ts, theCloudClient._path()method has the same TOCTOU race as the old client'sinit()(fixed in #7487).Affected code (~line 191)
When two operations (e.g. two simultaneous collection queries) call
_path()before_tenant/_databaseare populated:!this._tenant→ both enter the blockawait getUserIdentity()→ two concurrent auth callsthis._tenant = tenant→ last writer wins (no conflict here, but unnecessary double auth round-trip)getUserIdentity()returns different values across calls (e.g. due to token rotation), the final_tenantis non-deterministicSuggested fix
Same lazy-promise pattern used to fix
init():This ensures all concurrent callers await the same in-flight resolution.
Related
chromadb-coreclient'sinit()method