Gemini Interactions API — Video-to-Video Blobstore 400 Bug Report

## Summary

When submitting a video-to-video (edit/extend) request to the Interactions API in `background=true` + `store=true` mode with a source video referenced via a valid Files API URI (`https://generativelanguage.googleapis.com/v1beta/files/{id}\`), the POST succeeds and returns an `interaction_id`. However, every subsequent `GET /v1beta/interactions/{id}` returns HTTP 400 with:

```json

{

“error”: {

"message": "Unsupported file uri: blobstore:///genai-api/blobref/global::000050ecbb30026d:000002fa:2:000050ecbb30026d:0000000000000001...",

"code": "invalid_request"

}

}

```

The interaction can never be retrieved, so the generated video is permanently inaccessible to the client, despite the POST having succeeded.

## Environment

| Item | Value |

|—|—|

| Endpoint | `https://generativelanguage.googleapis.com/v1beta/interactions\` |

| API version | `v1beta` |

| Model | `gemini-omni-1.1-flash` |

| API key format | New-format key (`AQ.` prefix), passed via `x-goog-api-key` header |

| Task | Video-to-video (edit / extend) with source video uploaded via Files API |

| Mode | `background: true`, `store: true`, `stream: false`, `response_format.delivery: “uri”` |

| First observed | 2026-10-12 |

| Reproducibility | **100%** — every video-to-video request via Files API URI fails on GET |

## Reproduction Steps

### Step 1: Upload source video via Files API (resumable upload)

```

POST https://generativelanguage.googleapis.com/upload/v1beta/files

Headers:

x-goog-api-key: <API_KEY>

X-Goog-Upload-Protocol: resumable

X-Goog-Upload-Command: start

X-Goog-Upload-Header-Content-Length: 2072651

X-Goog-Upload-Header-Content-Type: video/mp4

Body: {“file”: {“display_name”: “video-source”}}

```

Then finalize the upload. Response:

```json

{

“file”: {

"name": "files/6kqzpdr3kct6",

"uri": "https://generativelanguage.googleapis.com/v1beta/files/6kqzpdr3kct6",

"state": "ACTIVE",

"mimeType": "video/mp4",

"sizeBytes": "2072651"

}

}

```

Polling `GET /v1beta/files/6kqzpdr3kct6` returns `state: “ACTIVE”`.

### Step 2: Submit interaction with the Files API URI

```

POST https://generativelanguage.googleapis.com/v1beta/interactions

Headers:

x-goog-api-key: <API_KEY>

Content-Type: application/json

Body:

{

“model”: “gemini-omni-1.1-flash”,

“stream”: false,

“background”: true,

“store”: true,

“response_format”: {

"type": "video",

"delivery": "uri"

},

“input”: [

{

  "type": "video",

  "uri": "https://generativelanguage.googleapis.com/v1beta/files/6kqzpdr3kct6",

  "mime_type": "video/mp4"

},

{

  "type": "text",

  "text": "<edit/extend instruction>"

}

]

}

```

**Response: HTTP 200** with:

```json

{

“id”: “v1_ChdiY0hNYXRxeUotMk1fUFVQcHYzS2lRMBIXYmNITWF0cXlKLTJNX1BVUHB2M0tpUTA”,

“status”: “in_progress”

}

```

### Step 3: Poll for the result

```

GET https://generativelanguage.googleapis.com/v1beta/interactions/v1_ChdiY0hNYXRxeUotMk1fUFVQcHYzS2lRMBIXYmNITWF0cXlKLTJNX1BVUHB2M0tpUTA

Headers:

x-goog-api-key: <SAME_API_KEY_AS_STEP_2>

```

**Actual response: HTTP 400**

```json

{

“error”: {

"message": "Unsupported file uri: blobstore:///genai-api/blobref/global::000050ecbb30026d:000002fa:2:000050ecbb30026d:0000000000000001...",

"code": "invalid_request"

}

}

```

**Expected response**: HTTP 200 with the interaction state (`in_progress` / `completed`) and, on completion, the generated video URI in `steps[].content[].uri`.

## Evidence from Production Logs

Full request/response trace from our production system (single request, recordId=3709):

```

19:15:45 Files API upload session started, source video downloaded (2,072,651 bytes)

19:15:47 Files API upload finalized:

      uri: https://generativelanguage.googleapis.com/v1beta/files/6kqzpdr3kct6

      name: files/6kqzpdr3kct6

19:15:57 File state polling: ACTIVE

19:15:57 POST /v1beta/interactions submitted with input[0] = {

        "type": "video",

        "uri":  "https://generativelanguage.googleapis.com/v1beta/files/6kqzpdr3kct6",

        "mime_type": "video/mp4"

      }

19:15:57 POST response 200: interactionId=v1_Chdi…, status=in_progress

19:15:58 GET /v1beta/interactions/v1_Chdi… with the SAME API key (keyId=2)

19:15:59 GET response 400: "Unsupported file uri: blobstore:///genai-api/blobref/global::

                         000050ecbb30026d:000002fa:2:000050ecbb30026d:0000000000000001..."

```

## Key Observations

### 1. Same API key used for POST and GET — this is NOT a cross-key permission issue

Both the Files API upload, the POST `/interactions`, and the GET `/interactions/{id}` use the exact same API key (identified internally as `keyId=2`, apiKey prefix `AQ.Ab8***yTtA`). The bug is not related to key rotation or cross-tenant access.

### 2. The blobstore URI is IDENTICAL across all failing interactions

Every failing GET (15+ different interactions, submitted over 4+ hours, with different source videos uploaded to different `files/{id}` endpoints) returns the **exact same blobstore URI**:

```

blobstore:///genai-api/blobref/global::000050ecbb30026d:000002fa:2:000050ecbb30026d:0000000000000001

```

This strongly suggests a **server-side template/placeholder** that is not being properly resolved per-interaction, rather than a legitimate per-file blob reference. The `:2:` segment in the URI matches our internal `keyId=2`, indicating the server correctly identifies the caller but produces a non-resolvable reference.

### 3. The client submits a valid, publicly-documented Files API URI

Per the [File input methods guide](https://ai.google.dev/gemini-api/docs/file-input-methods) and the [Omni Flash video editing docs](https://ai.google.dev/gemini-api/docs/omni), passing `https://generativelanguage.googleapis.com/v1beta/files/{id}\` as `input[].uri` is the officially recommended way to reference large videos (Base64 inlining is discouraged for videos due to the 33% size inflation and 20 MB request limit).

### 4. Varying `input[].type` does NOT help

We tested both:

| `type` value | Result |

|—|—|

| `“video”` + `uri` | 400 blobstore error |

| `“document”` + `uri` (matching the Python SDK example in the Omni docs) | **Same** 400 blobstore error, same blobstore URI |

The failure is triggered by the **URI reference itself**, not by the `type` discriminator.

### 5. POST succeeds; only GET fails

The interaction is created and (based on the response) enters `in_progress`. It is unclear whether the video is actually generated server-side, because the GET endpoint cannot serialize the stored state back to the client. This means:

- Billing may still occur for a video the client can never retrieve

- The client has no way to distinguish “still processing” from “permanently broken”

## Hypothesized Root Cause

When `background=true` + `store=true` is set, the Interactions service persists the interaction to an internal archive. During persistence, the valid external Files API URI (`https://generativelanguage.googleapis.com/v1beta/files/{id}\`) appears to be rewritten into an internal `blobstore:///genai-api/blobref/global::…` reference. When the GET endpoint later reads the archived interaction and tries to serialize it back to a client-consumable response, the serializer / validator rejects its own internal blobstore format with `“Unsupported file uri”`.

The fact that the blobstore URI is byte-identical across unrelated interactions supports this being a **template-resolution defect on the archival read path**, not a per-file corruption.

## Impact

- **All video-to-video (edit / extend) requests** submitted via `gemini-omni-1.1-flash` with Files API URI input are permanently broken at the retrieval step.

- Video generation via inline Base64 (`type: “video”` + `data: `, as in the REST curl example) still works, but this is impractical for realistic video sizes (>15 MB pre-Base64 hits the 20 MB request limit after 33% inflation).

- Text-to-video and image-to-video paths are unaffected (no Files URI in input).

## Requested Fix

Please investigate the Interactions archival read path so that GET `/v1beta/interactions/{id}` can correctly serialize interactions whose `input[]` contains a Files API URI reference. Either:

1. Resolve the internal `blobstore://` reference back to the original external `https://…/files/{id}` URI before returning the response, or

2. Skip serialization of `input[]` blob references when returning interaction state (the client already knows what it submitted), or

3. Return the resolved video output in `steps[].content[].uri` without echoing the input blob references.

## Workarounds Attempted

| Workaround | Result |

|—|—|

| Use the same API key for upload + POST + GET | ✗ Still 400 |

| Change `input[].type` from `“video”` to `“document”` | ✗ Still 400, same blobstore URI |

| Wait longer before polling (in case it’s a propagation delay) | ✗ Still 400 after 10+ minutes |

| Poll from a different network / IP | ✗ Still 400 |

The only currently working path is inline Base64 (`type: “video”` + `data: `), which is not viable for production video sizes.

## Additional Context

- Our integration follows the official docs precisely (Files API resumable upload → wait for `ACTIVE` → reference by `uri` in `input[]`).

- We have production traffic on this endpoint; the bug affects 100% of video-to-video requests since at least 2026-10-12.

- We are happy to provide additional logs, HAR files, or reproduce on demand with a specific interaction ID if helpful.

## Reference Interaction IDs (for Google backend log lookup)

Failing interactions observed in production (all returning identical blobstore URI):

| recordId | interactionId |

|—|—|

| 3709 | `v1_ChdiY0hNYXRxeUotMk1fUFVQcHYzS2lRMBIXYmNITWF0cXlKLTJNX1BVUHB2M0tpUTA` |

| 3716 | `v1_Chd4SlBOYXVEZkE4RFJ6N0lQcmZIMHlRMBIXeEpQTmF1RGZBOERSejdJUHJmSDB5UTA` |

| 3704 | `v1_ChdJN1BNYXVPMUJyN2lfdU1QeU96VTBBbxIXSTdQTWF1TzFCcjdpX3VNUHlPelUwQW8` |

| 3703 | `v1_ChYtYkxNYXA2bk1OU2cxTWtQZ08zQ0dBEhYtYkxNYXA2bk1OU2cxTWtQZ08zQ0dB` |

| 3695 | `v1_ChdQYXZNYXBlVUo3ZmNfdU1QaVBQM3dBRRIXUGF2TWFwZVVKN2ZjX3VNUGlQUDN3QUU` |

| 3694 | `v1_Chd2S3JNYW8zd0c2RDYtOFlQejZmc3NRbxIXdktyTWFvM3dHNkQ2LThZUHo2ZnNzUW8` |

| 3693 | `v1_ChdFYXJNYXJYU0xOSFZqckVQdElHVjhBURIXRWFyTWFyWFNMTkhWanJFUHRJR1Y4QVE` |

| 3691 | `v1_ChdwS25NYXJQUU9fellqTWNQb3J5YW9BVRIXcEtuTWFyUFFPX3pZak1jUG9yeWFvQVU` |

| 3690 | `v1_ChdFYW5NYXUySE1LQ21fdU1Qc082SGdBNBIXRWFuTWF1MkhNS0NtX3VNUHNPNkhnQTQ` |

| 3689 | `v1_Chc0S2pNYXA2WUx1NjJzT0lQNnZPU3FBTRIXNEtqTWFwNllMdTYyc09JUDZ2T1NxQU0` |

| 3679 | `v1_ChZZNXJNYXE3ZUdiZVAxTWtQemVLM0tBEhZZNXJNYXE3ZUdiZVAxTWtQemVLM0tB` |

| 3673 | `v1_ChdWSm5NYXNtaU1jNncxTWtQc3JQbTZRSRIXVkpuTWFzbWlNYzZ3MU1rUHNyUG02UUk` |

| 3672 | `v1_ChdvWmpNYXV5QlBOU1UzOUlQNElmY2lRWRIXb1pqTWF1eUJQTlNVMzlJUDRJZmNpUVk` |

Hello @Luo_Yin ,

A backend update was recently released to address this file resolution issue in background interactions.
Please retry your request and let us know if you still encounter any errors.