Get this on every PR automatically. Webhook fires, AI reviews, you approve.
Install on vercel/wait-for-deployment-action →
// reviewed by pulllight
PullLight found 3 issues
2 high
1 medium
// convert to your repo
PullLight caught 3 2 high, 1 medium on this PR.
Install on vercel/wait-for-deployment-action to get this on every PR automatically — 60 seconds.
Findings
3 issues
high
logic
When `vercelToken` is set, the `source` is `{ type: 'vercel', ... }` and the guard is `if (config.statusContext)`. This means that if `statusContext` is empty (deployment ID resolution disabled), the Vercel path is silently skipped even though the user explicitly provided a `vercelToken`. The Vercel lookup should be gated on `config.vercelToken`, not `config.statusContext`. A user who sets `vercel-token` but leaves `status-context` empty (or clears it) will never get a deployment ID, with no warning.
// src/run.ts:151
high
auth
`source.token` is interpolated directly into the `Authorization` header without any validation. If `vercel-token` is an empty string (the default in `action.yml`), the request is sent with `Authorization: Bearer ` — an unauthenticated call that will likely return a 401 or expose an error response. The caller in `run.ts` only checks `config.vercelToken` (truthy) before constructing the `vercel` source, but `resolveDeploymentIdFromUrl` itself has no guard. The `assert(response.ok, ...)` will catch the 401, but the error message will be confusing. More critically, if somehow an empty token reaches this function, it silently makes an unauthenticated API call.
// src/vercel.ts:23
⚡ Suggested fix
export async function resolveDeploymentIdFromUrl(
deploymentUrl: string,
source: VercelDeploymentIdSource,
): Promise<string> {
assert(source.token, 'Vercel token must not be empty');
const hostname = new URL(deploymentUrl).hostname;
medium
error-handling
`new URL(deploymentUrl)` will throw a `TypeError` if `deploymentUrl` is empty or not a valid URL. At the call site in `run.ts`, `deploymentUrl` is derived from the GitHub deployment status and could theoretically be an empty string if `environment_url` and `target_url` are both absent. The thrown `TypeError` will propagate uncaught past the `try/catch` that wraps `resolveDeploymentId`, since that catch block is only entered after this call. Actually looking at the diff more carefully, the `resolveDeploymentIdFromUrl` call IS inside the try block, so it will be caught — but the error message will be a raw `TypeError` rather than something actionable.
// src/vercel.ts:14