astral-sh/ruff · error · Error

Failed to save playground: ${response.status}

Error message

Failed to save playground: ${response.status}

What it means

Thrown by the ty playground's savePlayground when the POST of the multi-file project (files map plus current file name) to the share API returns a non-2xx status. The worker was reached but refused or failed to store the project.

Source

Thrown at playground/ty/src/Editor/api.ts:34

  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}`);
  }

  return await response.text();
}

View on GitHub (pinned to 672bb4edf0)

Solutions

  1. Inspect response.status in devtools to tell payload problems (4xx) from server problems (5xx)
  2. Retry once after a short delay for transient 5xx errors
  3. In local dev, restart `wrangler dev` so the current save route is served on localhost:8787
  4. Keep a local copy of the files; re-save after the worker recovers

Example fix

// before
const id = await savePlayground(playground);

// after
let id: string | null = null;
try {
  id = await savePlayground(playground);
} catch (error) {
  console.error((error as Error).message);
  // keep working locally; user can retry sharing
}
Defensive patterns

Strategy: try-catch

Validate before calling

const payload = JSON.stringify(playground);
if (!playground.current || !(playground.current in playground.files)) {
  throw new RangeError('Playground current file must exist in files');
}

Type guard

function isSavePayload(p: Playground): boolean {
  return Object.keys(p.files).length > 0 && p.current in p.files;
}

Try / catch

try {
  return await savePlayground(playground);
} catch (error) {
  console.error(`Save failed: ${(error as Error).message}`);
  return null;
}

Prevention

When it happens

Trigger: POST to API_URL with the JSON-serialized playground returning 5xx (worker/storage failure) or 4xx (rejected payload).

Common situations: Sharing a ty playground during a worker outage; very large multi-file payloads; local dev where the worker runs but the save route misbehaves.

Related errors


AI-assisted analysis of astral-sh/ruff@672bb4edf0 (2026-08-16). Data as JSON: /api/errors/66e3a8d0e6f5b4a5. Report an issue: GitHub.