windmill-labs/windmill · error
body.error || res.statusText
Error message
body.error || res.statusText
What it means
Inside the app-dev recorder page served by `wmill app dev --recording`, saving a recording POSTs the recording JSON to the configured `savePath`. If the HTTP response is not ok, the thrown error message is the `error` field of the JSON body, falling back to the HTTP status text. It surfaces whatever error the dev-server save handler reported.
Source
Thrown at cli/src/commands/app/devRecorder.ts:245
ticker = null;
toggle.classList.remove('recording');
toggleLabel.textContent = 'Record';
downloadBtn.hidden = false;
setStatus(steps(recording.steps.length) + ' recorded');
// Only now: starting a fresh recording drops the one being uploaded.
await save();
toggle.disabled = false;
}
async function save() {
try {
var res = await fetch(config.savePath, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(recording)
});
var body = await res.json();
if (!res.ok) throw new Error(body.error || res.statusText);
setStatus(steps(recording.steps.length) + ' saved to ' + body.file);
if (config.playerBaseUrl) {
var src = window.location.origin + config.savePath + '/' + body.file;
openLink.href = config.playerBaseUrl + 'replay?src=' + encodeURIComponent(src);
openLink.hidden = false;
}
} catch (e) {
setStatus('Recorded, but saving failed: ' + (e && e.message ? e.message : e));
}
}
toggle.addEventListener('click', function () {
if (recorder.active) stop();
else start();
});
downloadBtn.addEventListener('click', function () {
if (recording) recorder.download(recording);View on GitHub (pinned to e474e8803c)
Solutions
- Read the actual message: if it's a server-provided error, fix what the dev server reports (usually a file-write failure).
- Check that the recording output directory exists and is writable by the `wmill app dev` process.
- Reopen the recorder page / restart `wmill app dev --recording` to refresh the save endpoint config.
- If statusText like 'Not Found' is shown, the savePath config is stale — restart the dev session.
Example fix
var res = await fetch(config.savePath, { method: 'POST', ... });
var bodyText = await res.text();
if (!res.ok) throw new Error('Failed to save recording: ' + (bodyText || res.statusText)); Defensive patterns
Strategy: try-catch
Validate before calling
const res = await fetch(config.savePath, { method: 'HEAD' });
if (!res.ok) throw new Error('Recorder save endpoint not available at ' + config.savePath); Type guard
function isSaveOk(b: unknown): b is { file: string } { return typeof b === 'object' && b !== null && !('error' in b) && 'file' in b; } Try / catch
try { await saveRecording(recording) } catch (e) { setStatus('save failed: ' + e.message + ' — check server logs / output dir permissions'); } Prevention
- Ensure the recording output directory exists and is writable
- Restart the recorder page after restarting `wmill app dev`
- Check the HTTP status and response body text, not just the thrown message
When it happens
Trigger: The recording save endpoint returns a non-2xx response — e.g. the dev server failed to write the recording file to disk, the save path is misconfigured, or the server returned a JSON body with an `error` message (or no body, yielding statusText like 'Not Found' or 'Internal Server Error').
Common situations: Disk permission problems in the recording output directory; recorder save endpoint changed/moved between CLI versions; the dev server restarted and the page held a stale `savePath`; network hiccup during POST.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- HTTP ${res.status} ${res.statusText}
- Recording is too large (${total} bytes)
- Recording exceeded the size limit
- ${response.status} ${text}
- GET /assets/graph → ${res.status}
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/20320bb070ef144d.
Report an issue: GitHub.