Skip to content

Unable to upsert / upsertMany in DataConnect Emulator #8679

@Cruzor-Blade

Description

@Cruzor-Blade

[REQUIRED] Environment info

firebase-tools: 14.5.0

Platform: Windows

[REQUIRED] Test case

I have a schema defined as

type Application @table {
  id: String! @unique
  # other properties here
}

type Snapshot @table (key: [ "application", "version"]) {
  # The id property must be there, else, can't self reference
  id: UUID! @unique     @default(expr: "uuidV4()")
  application: Application!
  version: String!
  # other properties here
}

type Style @table (key: [ "id", "snapshot"]) {
  id: String!  
  prompt: String!
  snapshot: Snapshot!    @ref(references: "id")
# other properties here
}

and as soon as I try to upsert/upsertMany Style, the emulator crashes with the error

SQL query error: pq: unexpected message 'E'; expected ReadyForQuery
WITH  "style_upsertMany_0"  AS (INSERT INTO  "public"."style"  ( "created_at" , "id" , "prompt" , "snapshot_id" , "updated_at" ) VALUES (timestamptz '2025-05-30T07:56:18.850000Z','style','Anything Here !!!!!!!!!!!!!!','b587429f-1811-4aa9-93fc-10941508f69a'::uuid,timestamptz '2025-05-30T07:56:18.850000Z') ON CONFLICT ( "id" , "snapshot_id" ) DO UPDATE SET  "created_at" = excluded. "created_at" , "id" = excluded. "id" , "prompt" = excluded. "prompt" , "snapshot_id" = excluded. "snapshot_id" , "updated_at" = excluded. "updated_at"  RETURNING jsonb_build_object('id',  "id" , 'snapshotId', REPLACE(CAST(( "snapshot_id" ) AS text), '-', '')) AS j),  "style_upsertMany_1"  AS (INSERT INTO  "public"."style"  ( "created_at" , "id" , "prompt" , "snapshot_id" , "updated_at" ) VALUES (timestamptz '2025-05-30T07:56:18.850000Z','stylex','Some Text Describing what the expected outcome should look like','b587429f-1811-4aa9-93fc-10941508f69a'::uuid,timestamptz '2025-05-30T07:56:18.850000Z') ON CONFLICT ( "id" , "snapshot_id" ) DO UPDATE SET  "created_at" = excluded. "created_at" , "id" = excluded. "id" , "prompt" = excluded. "prompt" , "snapshot_id" = excluded. "snapshot_id" , "updated_at" = excluded. "updated_at"  RETURNING jsonb_build_object('id',  "id" , 'snapshotId', REPLACE(CAST(( "snapshot_id" ) AS text), '-', '')) AS j),  "style_upsertMany_temp"  AS (SELECT * FROM  "style_upsertMany_0"  UNION ALL SELECT * FROM  "style_upsertMany_1" ) SELECT coalesce(json_agg(j), '[]') FROM  "style_upsertMany_temp" 
Params: []

.
But If I insert /insertMany data, the command runs fine

[REQUIRED] Steps to reproduce

In DataConnect GraphQL files, try upserting the style infos

[REQUIRED] Expected behavior

To upsert the data properly and return the Styles key

[REQUIRED] Actual behavior

Crashes the entire emulators suite

dataconnect-debug.log:

I0530 11:01:35.797815   20032 load.go:37] Reloading schema and connectors...
I0530 11:01:35.856012   20032 control.go:73] [/emulator/backend 4a6f] UpdateResources(): done
Schema: sources: schema\schema.gql [2459B] 
Connector "default": sources: connector\users.queries.gql [791B] connector\applications.mutations.gql [3603B] connector\applications.queries.gql [2376B] connector\users.mutations.gql [969B] 
I0530 11:01:35.910477   20032 codegen.go:82] [connector "default" javascriptSdk] Generating sources into "C:\\Petit p\\densograph_2\\citygraph\\lib\\js\\default-connector"
I0530 11:01:35.937628   20032 collector.go:107] schema extensions wrote into "C:\\Petit p\\densograph_2\\backend\\dataconnect\\.dataconnect\\schema"
Generated sources: prelude.gql [71531B] main\implicit.gql [3786B] main\input.gql [70283B] main\relation.gql [41228B] main\query.gql [10088B] main\mutation.gql [27480B] 
I0530 11:01:35.942533   20032 collector.go:107] connector "default" javascriptSdk wrote into "C:\\Petit p\\densograph_2\\citygraph\\lib\\js\\default-connector"
Generated sources: react\index.d.ts [13204B] react\esm\package.json [17B] react\index.cjs.js [10377B] react\esm\index.esm.js [9766B] esm\index.esm.js [11259B] esm\package.json [17B] README.md [125595B] react\package.json [456B] react\README.md [130107B] index.d.ts [26740B] index.cjs.js [13004B] package.json [848B] 
I0530 11:01:35.951584   20032 installsdk.go:80] Running command: C:\Users\USER\AppData\Local\fnm_multishells\30576_1748595423183\npm.cmd install file:lib\js\default-connector
I0530 11:01:38.719237   20032 load.go:115] Finished reloading
I0530 11:01:38.720264   20032 dev.go:95] Listening on address (HTTP + gRPC): 127.0.0.1:9399
I0530 11:01:38.720264   20032 dev.go:95] Listening on address (HTTP + gRPC): [::1]:9399
I0530 11:01:40.802904   20032 migrate.go:24] Running migration SQL:
Step 1: ALTER TABLE "public"."style" DROP CONSTRAINT "style_pkey", ADD PRIMARY KEY ("id", "snapshot_id")
Step 2: DROP INDEX "public"."style_spec_styleId_idx"
Step 3: ALTER TABLE "public"."style_spec" DROP CONSTRAINT "style_spec_style_id_fkey", DROP COLUMN "title", ADD COLUMN "style_snapshot_id" uuid NOT NULL, ADD COLUMN "created_at" timestamptz NOT NULL, ADD COLUMN "enforced" boolean NOT NULL, ADD COLUMN "label" text NOT NULL, ADD CONSTRAINT "style_spec_style_id_style_snapshot_id_fkey" FOREIGN KEY ("style_id", "style_snapshot_id") REFERENCES "public"."style" ("id", "snapshot_id") ON DELETE CASCADE
Step 4: CREATE INDEX "style_spec_styleId_styleSnapshotId_idx" ON "public"."style_spec" ("style_id", "style_snapshot_id")
Step 5: CREATE UNIQUE INDEX "style_spec_id_uidx" ON "public"."style_spec" ("id")
E0530 11:01:40.810941   20032 service.go:89] [/emulator/backend 172d] failed to migrate schema: SQL migration error: failed to apply migration: failed to execute SQL migration
step 1 modify "style" table: pq: cannot drop constraint style_pkey on table style because other objects depend on it
SQL: ALTER TABLE "public"."style" DROP CONSTRAINT "style_pkey", ADD PRIMARY KEY ("id", "snapshot_id")
Original plan:
Step 1: ALTER TABLE "public"."style" DROP CONSTRAINT "style_pkey", ADD PRIMARY KEY ("id", "snapshot_id")
Step 2: DROP INDEX "public"."style_spec_styleId_idx"
Step 3: ALTER TABLE "public"."style_spec" DROP CONSTRAINT "style_spec_style_id_fkey", DROP COLUMN "title", ADD COLUMN "style_snapshot_id" uuid NOT NULL, ADD COLUMN "created_at" timestamptz NOT NULL, ADD COLUMN "enforced" boolean NOT NULL, ADD COLUMN "label" text NOT NULL, ADD CONSTRAINT "style_spec_style_id_style_snapshot_id_fkey" FOREIGN KEY ("style_id", "style_snapshot_id") REFERENCES "public"."style" ("id", "snapshot_id") ON DELETE CASCADE
Step 4: CREATE INDEX "style_spec_styleId_styleSnapshotId_idx" ON "public"."style_spec" ("style_id", "style_snapshot_id")
Step 5: CREATE UNIQUE INDEX "style_spec_id_uidx" ON "public"."style_spec" ("id")
I0530 11:01:40.841493   20032 control.go:73] [/emulator/backend 172d] UpdateResources(): done
Schema: sources: schema\schema.gql [2459B] 
Connector "default": sources: connector\users.queries.gql [791B] connector\applications.mutations.gql [3603B] connector\applications.queries.gql [2376B] connector\users.mutations.gql [969B] 
I0530 11:02:05.713112   20032 prepare.go:118] [operation "" attempt 1] preparePlan succeeded
I0530 11:02:05.713112   20032 prepare.go:109] [operation "" attempt 1] DBStats beforePrepare: sql.DBStats{MaxOpenConnections:1, OpenConnections:1, InUse:0, Idle:1, WaitCount:0, WaitDuration:0, MaxIdleClosed:0, MaxIdleTimeClosed:0, MaxLifetimeClosed:0}, afterPrepare: sql.DBStats{MaxOpenConnections:1, OpenConnections:1, InUse:0, Idle:1, WaitCount:0, WaitDuration:0, MaxIdleClosed:0, MaxIdleTimeClosed:0, MaxLifetimeClosed:0}
I0530 11:02:05.730166   20032 executor.go:97] [operation "" attempt 1] DBStats beforeRun: sql.DBStats{MaxOpenConnections:1, OpenConnections:1, InUse:0, Idle:1, WaitCount:0, WaitDuration:0, MaxIdleClosed:0, MaxIdleTimeClosed:0, MaxLifetimeClosed:0}, afterRun: sql.DBStats{MaxOpenConnections:1, OpenConnections:1, InUse:0, Idle:1, WaitCount:0, WaitDuration:0, MaxIdleClosed:0, MaxIdleTimeClosed:0, MaxLifetimeClosed:0}
I0530 11:02:05.730860   20032 engine.go:170] [/emulator/backend 172d] ExecuteGraphql : succeeded. 
I0530 11:02:09.758296   20032 prepare.go:118] [operation "" attempt 1] preparePlan succeeded
I0530 11:02:09.758296   20032 prepare.go:109] [operation "" attempt 1] DBStats beforePrepare: sql.DBStats{MaxOpenConnections:1, OpenConnections:1, InUse:0, Idle:1, WaitCount:0, WaitDuration:0, MaxIdleClosed:0, MaxIdleTimeClosed:0, MaxLifetimeClosed:0}, afterPrepare: sql.DBStats{MaxOpenConnections:1, OpenConnections:1, InUse:0, Idle:1, WaitCount:0, WaitDuration:0, MaxIdleClosed:0, MaxIdleTimeClosed:0, MaxLifetimeClosed:0}
I0530 11:02:09.768232   20032 executor.go:97] [operation "" attempt 1] DBStats beforeRun: sql.DBStats{MaxOpenConnections:1, OpenConnections:1, InUse:0, Idle:1, WaitCount:0, WaitDuration:0, MaxIdleClosed:0, MaxIdleTimeClosed:0, MaxLifetimeClosed:0}, afterRun: sql.DBStats{MaxOpenConnections:1, OpenConnections:0, InUse:0, Idle:0, WaitCount:0, WaitDuration:0, MaxIdleClosed:0, MaxIdleTimeClosed:0, MaxLifetimeClosed:0}
W0530 11:02:09.768232   20032 engine.go:174] [/emulator/backend 172d] ExecuteGraphql : failed. 
Auth: admin
Errors: input: style_upsertMany SQL query error: pq: unexpected message 'E'; expected ReadyForQuery
WITH  "style_upsertMany_0"  AS (INSERT INTO  "public"."style"  ( "created_at" , "id" , "prompt" , "snapshot_id" , "updated_at" ) VALUES (timestamptz '2025-05-30T07:56:18.850000Z','style','Anything Here !!!!!!!!!!!!!!','b587429f-1811-4aa9-93fc-10941508f69a'::uuid,timestamptz '2025-05-30T07:56:18.850000Z') ON CONFLICT ( "id" , "snapshot_id" ) DO UPDATE SET  "created_at" = excluded. "created_at" , "id" = excluded. "id" , "prompt" = excluded. "prompt" , "snapshot_id" = excluded. "snapshot_id" , "updated_at" = excluded. "updated_at"  RETURNING jsonb_build_object('id',  "id" , 'snapshotId', REPLACE(CAST(( "snapshot_id" ) AS text), '-', '')) AS j),  "style_upsertMany_1"  AS (INSERT INTO  "public"."style"  ( "created_at" , "id" , "prompt" , "snapshot_id" , "updated_at" ) VALUES (timestamptz '2025-05-30T07:56:18.850000Z','stylex','Some Text Describing what the expected outcome should look like','b587429f-1811-4aa9-93fc-10941508f69a'::uuid,timestamptz '2025-05-30T07:56:18.850000Z') ON CONFLICT ( "id" , "snapshot_id" ) DO UPDATE SET  "created_at" = excluded. "created_at" , "id" = excluded. "id" , "prompt" = excluded. "prompt" , "snapshot_id" = excluded. "snapshot_id" , "updated_at" = excluded. "updated_at"  RETURNING jsonb_build_object('id',  "id" , 'snapshotId', REPLACE(CAST(( "snapshot_id" ) AS text), '-', '')) AS j),  "style_upsertMany_temp"  AS (SELECT * FROM  "style_upsertMany_0"  UNION ALL SELECT * FROM  "style_upsertMany_1" ) SELECT coalesce(json_agg(j), '[]') FROM  "style_upsertMany_temp" 
Params: []

Data:
{
   "style_upsertMany": null
 }
sources: input [666B] 

for a reason I am unable to copy the full firebase-debug.log file contents as much of it is truncated. So, I attached the file instead

firebase-debug.log

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions