{"record":{"id":"bf00c68ee3ed8bc5","repo":"affaan-m/ECC","slug":"request-failed","errorCode":null,"errorMessage":"request failed","messagePattern":"request failed","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/control-pane/ui.js","lineNumber":664,"sourceCode":"    }\n\n    $('#query-form').addEventListener('submit', event => {\n      event.preventDefault();\n      state.query = $('#query').value.trim();\n      load().catch(error => showError('#app', error));\n    });\n    $('#refresh').addEventListener('click', () => {\n      load().catch(error => showError('#app', error));\n    });\n\n    async function postWorkItem(pathSuffix, payload) {\n      const response = await fetch('/api/work-items/' + pathSuffix, {\n        method: 'POST',\n        headers: { 'content-type': 'application/json' },\n        body: JSON.stringify(payload || {})\n      });\n      const result = await readJsonResponse(response);\n      if (!result.ok) throw new Error(result.error || 'request failed');\n      await load();\n    }\n\n    window.eccClaimItem = function (id) {\n      if (!state.allowActions) return;\n      const owner = window.prompt('Claim \"' + id + '\" as (owner name):');\n      if (!owner) return;\n      const as = (window.prompt(\"Owner kind: 'agent' or 'human'\", 'human') || '').trim().toLowerCase();\n      postWorkItem(encodeURIComponent(id) + '/claim', { owner: owner.trim(), as: as === 'agent' ? 'agent' : 'human' })\n        .catch(error => showError('#app', error));\n    };\n    window.eccMoveItem = function (id, lane) {\n      if (!state.allowActions) return;\n      postWorkItem(encodeURIComponent(id) + '/move', { lane })\n        .catch(error => showError('#app', error));\n    };\n\n    // Live board: refresh on a gentle interval; pause while a prompt/tab is hidden.","sourceCodeStart":646,"sourceCodeEnd":682,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/control-pane/ui.js#L646-L682","documentation":"Work-item action posts return { ok: boolean, error?: string }. When the handler completes successfully at HTTP level but reports ok:false, the client throws result.error or the generic 'request failed' fallback. This is a business-logic failure, not an HTTP failure.","triggerScenarios":"POST /api/work-items/<action> whose handler returns { ok: false } without an error message — e.g. mutation helper returned { claimed:false } path collapsed into a falsey ok, or handler omitted the error field.","commonSituations":"Claiming/moving a work item when the store operation partially fails, or a handler that sets ok:false but forgets to set error, so the UI shows only 'request failed'.","solutions":["Look at the server handler for the endpoint and find which path returns ok:false; the generic message means the error field was missing.","Ensure handlers always include an error string when ok is false: { ok: false, error: reason }.","Re-check the work item state — the mutation may have been rejected because the item is done, claimed, or missing.","Retry the action after refreshing the control pane state."],"exampleFix":"// before (server handler)\nreturn res.json({ ok: false });\n// after\nreturn res.json({ ok: false, error: 'no-unassigned-open-items' });","handlingStrategy":"type-guard","validationCode":"const result = await readJsonResponse(response);\nif (typeof result.ok !== 'boolean') throw new Error('Malformed API result');\nif (!result.ok && !result.error) throw new Error('API failed without error detail');","typeGuard":"function isActionOk(r) { return !!r && r.ok === true; }","tryCatchPattern":"try { await action(); } catch (e) {\n  if (e.message === 'request failed') console.error('Handler returned ok:false without an error message — inspect the server handler.');\n  else throw e;\n}","preventionTips":["Server handlers must always set an error string when ok is false.","Add an integration test asserting error payloads include an error field.","Refresh state before retrying mutations.","Treat 'request failed' as a handler bug to fix, not a client-side retryable condition."],"tags":["api","control-pane","error-handling"],"backgroundTag":"api-error-response","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}