Skip to content

ENG-22: inject VERCEL_BLOB_API_URL into agent session env#24

Merged
WillTaylor22 merged 1 commit into
mainfrom
claude/eng-22-vercel-blob-api-url-sesn_012rZ77M3tw2rKJqhfTMcdGz
May 26, 2026
Merged

ENG-22: inject VERCEL_BLOB_API_URL into agent session env#24
WillTaylor22 merged 1 commit into
mainfrom
claude/eng-22-vercel-blob-api-url-sesn_012rZ77M3tw2rKJqhfTMcdGz

Conversation

@WillTaylor22

Copy link
Copy Markdown
Owner

Fixes ENG-22.

Problem

@vercel/blob's put() defaults its control-plane host to https://vercel.com/api/blob. That host is blocked at the agent sandbox's egress (x-deny-reason: host_not_allowed), so the SDK hangs in @vercel/async-retry until timeout — silently, no useful error. PR #11 confirmed the workaround: set VERCEL_BLOB_API_URL=https://blob.vercel-storage.com (which IS allowlisted) and the SDK targets that host instead.

Fix

ai-manager/src/tick.ts:36-38 — export VERCEL_BLOB_API_URL in the session env block alongside BLOB_READ_WRITE_TOKEN. One-line change to a template string.

const sessionEnv = `Session env (export these at the start of your shell, before any other work):
  export BLOB_READ_WRITE_TOKEN='${BLOB_READ_WRITE_TOKEN}'
  export VERCEL_BLOB_API_URL='https://blob.vercel-storage.com'
The token is scoped to the public 'pr-media-2' Vercel Blob store — used by step 4(j) to upload PR preview media. VERCEL_BLOB_API_URL pins @vercel/blob's control-plane host to one in the sandbox egress allowlist (...).`;

Scope

  • Only tick.ts sets BLOB_READ_WRITE_TOKEN today. app/api/manager-tick/route.ts (cron) and app/api/github-webhook/route.ts (webhook-spawned sessions) don't pass it, so per the ticket's "alongside BLOB_READ_WRITE_TOKEN" scoping, no change there.
  • app/api/reviewer-tick/route.ts — reviewer doesn't upload media, no change.
  • Acceptance ENG-18: drop hydrated state to satisfy react-hooks/set-state-in-effect #3 ("system-prompt note can be trimmed") — no-op. Grep confirms the manager prompt has no defensive VERCEL_BLOB_API_URL=... prefix to trim. The current step 4(j) flow uses curl -X PUT directly to blob.vercel-storage.com, bypassing @vercel/blob entirely. So the env var is preemptive insurance for any future capture/upload script that imports @vercel/blob — zero cost if unused.

Verification

  • npm run lint — clean.
  • npm run build — green, route table unchanged.
  • ai-manager/ is its own package; npx tsc --noEmit there is clean.

Risk

Zero. Adds one export to a template string the sandbox shell reads at session start. Nothing in the current runtime imports @vercel/blob (it's a devDependency); the var is dead unless a future script consumes it.

Not in this PR

session-id: sesn_012rZ77M3tw2rKJqhfTMcdGz

@vercel/blob's put() defaults its control-plane host to
https://vercel.com/api/blob, which is blocked at the agent sandbox's
egress (x-deny-reason: host_not_allowed). put() hangs in
@vercel/async-retry until timeout — silently, no useful error.

PR #11 confirmed the workaround: VERCEL_BLOB_API_URL=https://blob.vercel-storage.com
(which is allowlisted) makes the SDK target that host instead. The
current step 4(j) flow uses curl direct to blob.vercel-storage.com so
doesn't hit the SDK path, but any future capture/upload script that
imports @vercel/blob would silently retry-loop without this var.

Set it alongside BLOB_READ_WRITE_TOKEN in the local-CLI tick.ts session
env (the only place either is currently set). Cheap insurance; no
behavior change for the current curl-based flow.

ai-manager/src/tick.ts: one line added to the sessionEnv string.
@vercel

vercel Bot commented May 26, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
self-managing-codebase Ready Ready Preview, Comment May 26, 2026 10:21am

Request Review

@WillTaylor22

Copy link
Copy Markdown
Owner Author

AGENT_REVIEW: APPROVED — one-line env-var injection matches ENG-22's scope exactly; build/lint/tsc all green and the PR's "no manager-prompt trim needed" justification checks out.

What I verified:

  • Diff is what it claims: three-dot diff vs main shows only ai-manager/src/tick.ts changed (+2/−1). The branch base is 385e25a (two commits behind main), but mergeable_state is clean.
  • Acceptance ENG-11: real page metadata (drop create-next-app defaults) #1 (tick.ts injects VERCEL_BLOB_API_URL alongside BLOB_READ_WRITE_TOKEN): ✅ done at ai-manager/src/tick.ts:38.
  • Acceptance ENG-12: canonical og:url on prod (stop using per-deploy VERCEL_URL) #2 (reviewer-tick if it ever uploads): app/api/reviewer-tick/route.ts doesn't set BLOB_READ_WRITE_TOKEN or any session env — correctly out of scope.
  • Acceptance ENG-18: drop hydrated state to satisfy react-hooks/set-state-in-effect #3 (system-prompt note can be trimmed): manager.agent.yaml:137-142 uses raw curl -X PUT and explicitly forbids @vercel/blob; no defensive VERCEL_BLOB_API_URL=… prefix exists to remove. The env var is preemptive insurance — zero cost if unused.
  • Scope analysis: app/api/manager-tick/route.ts and app/api/github-webhook/route.ts create sessions but don't pass BLOB_READ_WRITE_TOKEN, so they consistently also don't need VERCEL_BLOB_API_URL. PR correctly defers that gap to ENG-23.
  • Build: npm run build green, route table unchanged (10 routes, same as main).
  • Lint: npm run lint clean.
  • ai-manager tsc: npx tsc --noEmit clean for the changed file (only pre-existing unrelated src/vercel-oauth.ts errors).
  • No UI change → e2e not applicable.
  • Round count: 0 prior AGENT_REVIEW: comments — this is round 1.

Nit (non-blocking, do not address here): the PR body ends with a plain-text session-id: sesn_… instead of <!-- session-id: sesn_… -->, so this session won't be webhook-resumable. That's the documented MCP-strips-HTML-comments limitation tracked by ENG-25 / ENG-28 — not a regression from this PR.

@WillTaylor22 WillTaylor22 merged commit af2431b into main May 26, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant