## TL;DR

`Response.redirect` requires an absolute URL, and workerd throws the moment you hand it a relative path like "/login". Browsers are lenient about this in some paths, workerd is not. Build the target with `new URL(path, request.url)` so it is always absolute, then redirect.

```text
TypeError: Response constructor: invalid redirect value
```

## Steps

1. Find the throwing redirect call. Search your worker for Response.redirect:
```sh
grep -rn "Response.redirect" src
```
Expected: one or more call sites; the throwing one passes a relative path or a malformed string.

2. Make the target absolute using the incoming request as the base:
```js
const url = new URL("/login", request.url);
return Response.redirect(url.toString(), 301);
```
Expected: no relative paths reach Response.redirect anywhere in the handler.

3. Confirm the status code is a real redirect status: 301, 302, 303, 307, or 308. Anything else with a Location header trips the same validation.
Expected: the status is one of those five.

4. Test locally and check the response:
```sh
wrangler dev
```
Then request the redirecting route and confirm you get a 301 with a correct absolute Location header.
Expected: 301 status, Location header present and absolute, no exception in the dev log.

## Use this when
- Workerd throws "Response constructor: invalid redirect value" on a redirect
- A redirect that works in the browser throws inside the worker
- You are constructing redirect targets from user input or route params

## Not for this skill when
- The redirect returns but points at the wrong place; that is a logic bug, not this error
- The error comes from a framework helper rather than a direct Response.redirect call
- You are investigating whether it is a workerd bug (use the issue-search skill)

## Variant phrasings
- TypeError invalid redirect value workerd
- Response.redirect throws in cloudflare worker
- workerd redirect Location header invalid

## Why it happens

The Fetch spec requires redirect responses to carry a valid absolute URL, and workerd validates the value strictly at construction time. A relative path fails URL parsing, so the constructor throws instead of returning a broken response. Code that ran fine in Node or the browser, where some redirect paths tolerate relative targets, breaks on this strictness.

## Edge cases
- Redirect targets built from user input can contain spaces or unicode; encode them before constructing the URL or the parse fails the same way.
- In tests, `request.url` may be a fake origin; make sure the base you pass to new URL is a valid absolute URL or the helper throws instead.
- 307 and 308 preserve the request method; switching status codes to dodge the error changes semantics, so fix the URL instead.
- Middleware that rewrites the Location header after the redirect is constructed can reintroduce a relative value; check the final response, not just the constructor call.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_phKUC2mdzWzmm2opWau0zg
