thedotmack/claude-mem · error · Error
Failed to fetch logs
Error message
Failed to fetch logs: ${response.statusText} What it means
LogsDrawer fetches log content from the viewer's internal /api/logs endpoint. If the HTTP response is not ok (non-2xx), it throws an Error embedding response.statusText, which is caught and shown in the drawer's error state. It signals the log-serving backend failed for this request.
Solutions
- Check the viewer backend is running and serving /api/logs (curl it directly and inspect status/body)
- Inspect the network tab for the actual status code and response body; fix the server-side error reported there
- Fix dev-server/proxy config so /api/logs is forwarded to the viewer API
- Verify the log file the endpoint reads exists and is readable by the server process
Example fix
// before
const response = await fetch('/api/logs');
if (!response.ok) {
throw new Error(`Failed to fetch logs: ${response.statusText}`);
}
// after
const response = await fetch('/api/logs');
if (!response.ok) {
const body = await response.text();
throw new Error(`Failed to fetch logs: ${response.status} ${response.statusText} - ${body}`);
} Defensive patterns
Strategy: try-catch
Validate before calling
const res = await fetch('/api/logs');
if (!res.ok) throw new Error(`logs endpoint ${res.status}`); Type guard
function isOk(r: Response): boolean { return r.ok; } Try / catch
try {
const res = await fetch('/api/logs');
if (!res.ok) throw new Error(`Failed to fetch logs: ${res.status} ${res.statusText}`);
const data = await res.json();
} catch (err) {
showError(err instanceof Error ? err.message : 'Unknown error');
} Prevention
- Always check response.ok before parsing JSON
- Include response.status and response body in error messages for debuggability
- Health-check the viewer API before rendering the logs UI
- Alert on server-side /api/logs failures
When it happens
Trigger: fetch('/api/logs') returns a non-ok status, e.g. viewer server not running / proxied incorrectly, endpoint returning 404/500, or a dev-server proxy misroute returning 404.
Common situations: Opening the Logs modal while the viewer's API server is down or restarted; reverse-proxy not forwarding /api/*; the logs endpoint erroring while reading the log file (permissions, missing file); stale UI bundle pointed at a server without the /api/logs route.
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
- [claude-mem] Worker GET
- [claude-mem] Worker POST
- Failed to clear logs
- classifyClaudeServerError
- classifyGeminiError( )
AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17).
Data as JSON: /api/errors/1a40c77196db0911.
Report an issue: GitHub.
Appendix: source
Thrown at src/ui/viewer/components/LogsModal.tsx:124
const { scrollTop, scrollHeight, clientHeight } = contentRef.current;
return scrollHeight - scrollTop - clientHeight < 50;
}, []);
const scrollToBottom = useCallback(() => {
if (contentRef.current && wasAtBottomRef.current) {
contentRef.current.scrollTop = contentRef.current.scrollHeight;
}
}, []);
const fetchLogs = useCallback(async () => {
wasAtBottomRef.current = checkIfAtBottom();
setIsLoading(true);
setError(null);
try {
const response = await fetch('/api/logs');
if (!response.ok) {
throw new Error(`Failed to fetch logs: ${response.statusText}`);
}
const data = await response.json();
setLogs(data.logs || '');
} catch (err) {
setError(err instanceof Error ? err.message : 'Unknown error');
} finally {
setIsLoading(false);
}
}, [checkIfAtBottom]);
useEffect(() => {
scrollToBottom();
}, [logs, scrollToBottom]);
const handleClearLogs = useCallback(async () => {
if (!confirm('Are you sure you want to clear all logs?')) {
return;
}View on GitHub (pinned to d8bc9755e7)