Package: @firebaseextensions/firestore-bigquery-change-tracker, src/bigquery/initializeLatestView.ts on next.
The existing-view path aliases the module-level constant and mutates it:
const schema = RawChangelogViewSchema; // line 77
...
if (config.wildcardIds) {
schema.fields.push(documentPathParams); // line 86
}
The create path copies first (const schema = { fields: [...RawChangelogViewSchema.fields] }, line 124), so only the update path leaks. Each initializeLatestView call in the same process with wildcardIds set appends another path_params field to the shared constant. Later readers of RawChangelogViewSchema in the same process see the duplicates, including view.setMetadata({ schema: RawChangelogViewSchema }) on line 144 of the create path.
In a long-lived function instance that initialises more than once (several trackers, or the initBigQuerySync task followed by the trigger) the schema sent to BigQuery grows by one duplicate path_params per init. BigQuery rejects duplicate column names in a schema update, so after the first re-init the update path fails until the instance is recycled.
Fix: copy on the update path the same way the create path does.
const schema = { fields: [...RawChangelogViewSchema.fields] };
And pin it with a test that calls initializeLatestView twice with wildcardIds: true and asserts RawChangelogViewSchema.fields is unchanged.
Found during the adversarial review of #3137. Not reproduced live.
Package:
@firebaseextensions/firestore-bigquery-change-tracker,src/bigquery/initializeLatestView.tsonnext.The existing-view path aliases the module-level constant and mutates it:
The create path copies first (
const schema = { fields: [...RawChangelogViewSchema.fields] }, line 124), so only the update path leaks. EachinitializeLatestViewcall in the same process withwildcardIdsset appends anotherpath_paramsfield to the shared constant. Later readers ofRawChangelogViewSchemain the same process see the duplicates, includingview.setMetadata({ schema: RawChangelogViewSchema })on line 144 of the create path.In a long-lived function instance that initialises more than once (several trackers, or the
initBigQuerySynctask followed by the trigger) the schema sent to BigQuery grows by one duplicatepath_paramsper init. BigQuery rejects duplicate column names in a schema update, so after the first re-init the update path fails until the instance is recycled.Fix: copy on the update path the same way the create path does.
And pin it with a test that calls
initializeLatestViewtwice withwildcardIds: trueand assertsRawChangelogViewSchema.fieldsis unchanged.Found during the adversarial review of #3137. Not reproduced live.