Skip to content

Uploading the Avatar Reference to R2

Detailed mechanics of getting an avatar reference photo from your laptop to a public R2 URL the pipeline can use. Most of the time this is one Claude command, but knowing what's happening underneath matters when something goes wrong.

What you're doing

flowchart LR
    A[Local file<br/>reference/avatar-sheets/account-x.jpg] --> B[Worker proxy<br/>patchwork-r2-upload.workers.dev]
    B --> C[Cloudflare R2 bucket]
    C --> D[Public CDN URL<br/>pub-xxx.r2.dev/account-x.jpg]
    D --> E[Recorded in r2-urls.md]

The file goes through a Cloudflare Worker proxy (not directly to R2 with your credentials). The Worker handles authentication; you just send the file. The Worker writes to the R2 bucket and returns a public URL.

The one-liner

You: upload reference/avatar-sheets/account-x.jpg to R2

Claude: [uploads via the Worker, returns the URL, appends to r2-urls.md]

That's it for normal usage. The Worker handles everything.

What the Worker proxy does

The Worker (hosted at https://patchwork-r2-upload.patchworkstudio.workers.dev) does three things:

  1. Authenticates the upload using a baked-in service token (not your credentials)
  2. Writes the file to the R2 bucket at the configured path
  3. Returns the public URL of the uploaded file

No credentials live on your machine. The Worker has access; you have access to the Worker. This is the same path the Generation Runner uses when it uploads reference images automatically.

URL structure

R2 public URLs look like:

https://pub-{bucket-prefix}.r2.dev/{path}/{filename}.{ext}

For avatar reference sheets, the path is typically:

https://pub-xxxxx.r2.dev/avatar-sheets/{account-code}.{jpg|png}

The account-code matches the account's code in the version registry. Filename and account code stay consistent so future workflows can find the URL programmatically.

Recording the URL

After upload, the URL goes into reference/avatar-sheets/r2-urls.md:

# Avatar Reference Sheet R2 URLs

| Account | Local file | R2 URL |
|---|---|---|
| A | account-a.jpg | https://pub-xxx.r2.dev/avatar-sheets/account-a.jpg |
| B | account-b.jpg | https://pub-xxx.r2.dev/avatar-sheets/account-b.jpg |
| C | account-c.jpg | https://pub-xxx.r2.dev/avatar-sheets/account-c.jpg |

This manifest is what future workflows read to find each account's avatar reference. Always update it when you upload.

Versioning the avatar reference

Sometimes you re-upload a refined avatar reference (better lighting, refined photo). Two options:

Replace in place (same URL)
Upload to the same path. The URL doesn't change but the file at that URL is the new version. Risk: if any workflow has cached the old image, you may get inconsistent behavior. Avoid unless you're 100% sure no workflow needs the old version.
Upload a new version with a suffix
account-x-v2.jpg, account-x-v3.jpg, etc. The URL changes. Update r2-urls.md to point to the latest. Workflows using the old URL keep working unchanged; new workflows get the new ref.

Default to versioned suffix unless you have a clear reason to replace in place.

When a URL goes 404

Sometimes a reference URL stops resolving — maybe a bucket got cleaned up, or the path was wrong. Symptoms:

  • The Generation Runner produces broken / random faces
  • PatchWork can't preview the Media node
  • The Worker returns a 404 when you hit the URL directly

Recovery:

  1. Find the original local file (reference/avatar-sheets/{account-code}.{jpg|png})
  2. Re-upload via the Worker (this writes fresh to R2)
  3. Verify the URL resolves in a browser
  4. Update r2-urls.md if the URL changed
  5. Update any workflows that hardcoded the old URL (Surgical edits — see Chapter 3)

Direct R2 upload (advanced — rarely needed)

If the Worker proxy is unavailable (rare), you can upload directly to R2 using wrangler or the R2 dashboard. This requires R2 API credentials, which are sensitive.

Default: use the Worker. Direct upload is only for the team admin handling exceptional cases.

Bandwidth and storage notes

R2 has generous quotas. You're not going to hit them through normal avatar uploads. Each avatar reference is ~500KB to 2MB; you could upload thousands without issue.

The places R2 usage actually adds up:

  • Generated outputs — every gen produces 4 images (a few MB each); a busy production week adds gigabytes
  • Generated videos — Veo clips are tens of MB each
  • Old -generated.nbflow files — accumulate over time

The pipeline's R2 lifecycle policy (if any) handles old outputs. Avatar references stay forever — they're tiny and reused.

When you're ready

Next: Setting up Sales Channel Mechanics — TikTok Shop link, ManyChat keyword automation, the practical steps to wire up the conversion path.