astral-sh/ruff · error · Error
Failed to fetch playground ${id}: ${response.status}
Error message
Failed to fetch playground ${id}: ${response.status} What it means
Thrown by the ty playground's fetchPlayground when the backend answers a non-2xx status. The ty playground stores multi-file projects (a files map plus the current file name) on the share API worker, and this error means the server was reached but refused or failed the lookup.
Source
Thrown at playground/ty/src/Editor/api.ts:18
const API_URL = import.meta.env.PROD
? "https://api.astral-1ad.workers.dev"
: "http://localhost:8787";
export type Playground = {
files: { [name: string]: string };
/// the name of the current file
current: string;
};
/**
* Fetch a playground by ID.
*/
export async function fetchPlayground(id: string): Promise<Playground | null> {
const response = await fetch(`${API_URL}/${encodeURIComponent(id)}`);
if (!response.ok) {
throw new Error(`Failed to fetch playground ${id}: ${response.status}`);
}
return await response.json();
}
/**
* Save a playground and return its ID.
*/
export async function savePlayground(playground: Playground): Promise<string> {
const response = await fetch(API_URL, {
method: "POST",
body: JSON.stringify(playground),
});
if (!response.ok) {
throw new Error(`Failed to save playground: ${response.status}`);
}
View on GitHub (pinned to 672bb4edf0)
Solutions
- Verify the ID in the URL is complete and unmodified
- Confirm the API worker deployment is healthy, then retry the load
- Ask the sender to re-share the playground if the stored entry expired
- In local dev, start the worker on localhost:8787 before loading shared links
Example fix
// before
const playground = await fetchPlayground(id);
// after
try {
const playground = await fetchPlayground(id);
} catch (error) {
console.error((error as Error).message);
// fall back to the default playground files
} Defensive patterns
Strategy: try-catch
Validate before calling
const ID_RE = /^[A-Za-z0-9_-]{4,}$/;
if (!ID_RE.test(id)) {
throw new RangeError(`Invalid playground id: ${id}`);
} Type guard
function isPlayground(v: unknown): v is Playground {
return (
typeof v === 'object' && v !== null &&
typeof (v as Playground).current === 'string' &&
typeof (v as Playground).files === 'object' &&
(v as Playground).files !== null &&
Object.values((v as Playground).files).every((f) => typeof f === 'string')
);
} Try / catch
try {
const playground = await fetchPlayground(id);
if (!isPlayground(playground)) return defaults();
return playground;
} catch (error) {
console.error(`Could not load shared playground: ${(error as Error).message}`);
return defaults();
} Prevention
- Never hand-edit IDs in shared ty playground URLs
- Validate the parsed files map before populating the editor tabs
- Fall back to the default project on any load failure
When it happens
Trigger: GET `${API_URL}/${encodeURIComponent(id)}` returning 404 for an unknown, mistyped, or expired playground ID, or 5xx from a failing worker.
Common situations: Opening stale share links whose snippet expired; manually editing the ID in the URL; worker outage or partial deployment.
Related errors
- Failed to fetch playground ${id}: ${response.status}
- Failed to save playground: ${response.status}
- Failed to save playground: ${response.status}
- Git fetch of commit {} failed: {}
- Git clone failed: {}
AI-assisted analysis of astral-sh/ruff@672bb4edf0 (2026-08-16).
Data as JSON: /api/errors/41c9304cb08ef1a3.
Report an issue: GitHub.