affaan-m/ECC · error · Error
(payload.error || status + ' ' + statusText)
Error message
(payload.error || status + ' ' + statusText)
What it means
After parsing, readJsonResponse checks response.ok. For non-2xx responses it throws the server-supplied payload.error, or falls back to '<status> <statusText>'. This surfaces HTTP-level failures from the control-pane API to the UI caller.
Solutions
- Read the thrown detail string — it is either the API's error message or the HTTP status; match it to the failing endpoint.
- Verify the request payload shape matches what the route handler validates.
- Check that the work item / route referenced still exists (stale UI state after another agent moved/deleted it).
- Add server-side logging in the route to capture why it returned a non-2xx status.
Defensive patterns
Strategy: try-catch
Validate before calling
if (!response.ok) {
const body = await response.text();
console.error('API failed', response.status, body.slice(0, 500));
} Type guard
function isApiErrorPayload(p) { return !!p && typeof p === 'object' && typeof p.error === 'string'; } Try / catch
try { await postWorkItemAction(path, payload); } catch (e) {
if (/^\d{3} /.test(e.message)) console.error('HTTP failure:', e.message);
else throw e;
} Prevention
- Always return a JSON error body with an error field from API routes.
- Keep the UI's item list in sync (refetch after mutations) to avoid stale-id 404s.
- Validate payloads client-side to avoid 400s.
- Log non-2xx responses server-side with the reason.
When it happens
Trigger: Any POST/GET to /api/work-items/* that the server rejects: 400 bad body, 404 unknown route/id, 500 handler exception — thrown with the API's error string or the status code.
Common situations: Stale page posting a work item id that no longer exists (404), invalid lane/action payload (400), or server bug producing 500 with an error field.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- request failed
- ${result.error || 'request failed'}
- returned
- unsupported plan-canvas request path
- Codex review failed ` : ''}
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/06e09e9410082230.
Report an issue: GitHub.
Appendix: source
Thrown at scripts/lib/control-pane/ui.js:449
function clearError(targetSelector) {
const target = $(targetSelector);
if (!target) return;
target.hidden = true;
target.textContent = '';
}
async function readJsonResponse(response) {
let payload;
try {
payload = await response.json();
} catch (error) {
throw new Error('Expected JSON response from control pane: ' + error.message);
}
if (!response.ok) {
const detail = payload && payload.error ? payload.error : response.status + ' ' + response.statusText;
throw new Error(detail);
}
return payload;
}
function statePill(stateName) {
const state = String(stateName || 'unknown');
const klass = ['running', 'done'].includes(state)
? 'good'
: ['failed', 'blocked'].includes(state)
? 'bad'
: ['pending', 'ready'].includes(state)
? 'warn'
: 'blue';
return '<span class="pill ' + klass + '">' + escapeHtml(state) + '</span>';
}
function renderMetrics(summary) {View on GitHub (pinned to 8321021c54)