sveltejs/kit · error · Error
`redirect` options.external must be `true` or an array of al
Error message
`redirect` options.external must be `true` or an array of allowed origins (prod: 'Invalid redirect options.external value')
What it means
The `external` option of `redirect()` accepts only `true` (allow any external URL) or an array of allowed origin strings/patterns. Any other value (number, object, string, false, null) fails validation and throws, with a generic production message.
Source
Thrown at packages/kit/src/exports/url.js:81
);
}
return;
}
if (Array.isArray(external)) {
if (!external.some((allowed) => matches_external_allowlist_entry(location, allowed))) {
throw new Error(
DEV
? `Cannot redirect to ${JSON.stringify(location)}: URL origin is not included in the \`external\` allowlist`
: 'Cannot redirect to external URL unless explicitly allowed'
);
}
return;
}
throw new Error(
DEV
? '`redirect` options.external must be `true` or an array of allowed origins'
: 'Invalid redirect options.external value'
);
}
View on GitHub (pinned to 03f1687fe6)
Solutions
- Wrap a single origin in an array: `external: ['https://example.com']`
- Use `external: true` if all external URLs should be allowed
- Remove the option if you only redirect to same-origin relative URLs
- Check where the value is generated — an undefined/empty config value often becomes an invalid type
Example fix
// before
redirect(302, url, { external: 'https://example.com' });
// after
redirect(302, url, { external: ['https://example.com'] }); Defensive patterns
Strategy: validation
Validate before calling
const ext = options.external;
if (ext !== undefined && ext !== true && !(Array.isArray(ext) && ext.every((e) => typeof e === 'string'))) {
throw new TypeError('external must be true or an array of origin strings');
} Type guard
function isValidExternalOption(v) {
return v === true || (Array.isArray(v) && v.every((e) => typeof e === 'string'));
} Try / catch
try {
redirect(status, location, { external });
} catch (err) {
if (/Invalid redirect options.external/.test(err.message)) {
console.error('external option must be true or string[]; got', typeof external);
}
throw err;
} Prevention
- Always wrap single origins in an array: external: ['https://x.com']
- Type the options in TS so invalid shapes fail at compile time
- Centralize redirect calls in a helper that validates options once
When it happens
Trigger: Passing `redirect(302, url, { external: 'https://example.com' })` (a bare string instead of an array), `{ external: false }`, `{ external: 1 }`, or forgetting the option shape entirely.
Common situations: Misreading the docs and passing a single origin string instead of wrapping it in an array; dynamically computing `external` from env config that ends up empty/undefined; older code written against a different API shape.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- The SvelteKit Vite plugin ${keypath} should be an object wit
- Invalid status code
- Invalid redirect location ${JSON.stringify(location)}: this
- Cannot redirect to external URL ${JSON.stringify(location)}.
- Cannot redirect to ${JSON.stringify(location)} with `{ exter
AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02).
Data as JSON: /api/errors/82603fcdf829e915.
Report an issue: GitHub.