sickn33/agentic-awesome-skills · error · Error
HTTP ${res.status}
Error message
HTTP ${res.status} What it means
In the fp-react skill's fetch wrapper, this error is thrown when the HTTP response's `ok` flag is false — any 4xx or 5xx status. The throw happens inside TE.tryCatch's attempt function, so it is automatically captured as the Left of the TaskEither rather than escaping to the caller.
Source
Thrown at skills/fp-react/SKILL.md:254
## 3. Data Fetching with TaskEither
TaskEither = async operation that might fail. Perfect for API calls.
### Basic Fetch Hook
```typescript
import { useState, useEffect } from 'react'
import * as TE from 'fp-ts/TaskEither'
import * as E from 'fp-ts/Either'
import { pipe } from 'fp-ts/function'
// Wrap fetch in TaskEither
const fetchJson = <T>(url: string): TE.TaskEither<Error, T> =>
TE.tryCatch(
async () => {
const res = await fetch(url)
if (!res.ok) throw new Error(`HTTP ${res.status}`)
return res.json()
},
(err) => err instanceof Error ? err : new Error(String(err))
)
// Custom hook
function useFetch<T>(url: string) {
const [data, setData] = useState<T | null>(null)
const [error, setError] = useState<Error | null>(null)
const [loading, setLoading] = useState(true)
useEffect(() => {
setLoading(true)
setError(null)
pipe(
fetchJson<T>(url),
TE.match(View on GitHub (pinned to 58d857988f)
Solutions
- Inspect res.status (and the response body) before assuming a client bug — the number identifies the class of failure
- Ensure auth tokens and correct base URL/headers are attached to fetch
- Handle the Left branch of the TaskEither to show user-facing messages per status code
Example fix
// before
const res = await fetch(url)
if (!res.ok) throw new Error(`HTTP ${res.status}`)
// after: enrich the Left with status and body
const fetchJson = <T>(url: string): TE.TaskEither<Error, T> =>
TE.tryCatch(
async () => {
const res = await fetch(url)
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`)
return res.json()
},
(err) => err instanceof Error ? err : new Error(String(err))
) Defensive patterns
Strategy: try-catch
Type guard
const isOkStatus = (s: number) => s >= 200 && s < 300
Try / catch
// with TaskEither the throw never escapes; handle the Left: pipe( fetchJson<T>(url), TE.mapLeft((e) => e.message /* e.g. 'HTTP 401' */) )
Prevention
- Attach auth headers and correct base URL to every fetch
- Map status codes to user-facing messages centrally instead of letting raw Errors bubble
When it happens
Trigger: Any fetch(url) returning a non-2xx status: 401 with an expired token, 404 on a mistyped endpoint, 500 from the server, or a 429 rate limit.
Common situations: Missing or expired auth headers in the fetch call; proxy/dev-server rewriting API paths; backend deployed with breaking route changes; CORS preflight failures surfacing as opaque errors.
Related errors
- HTTP ${response.status}: ${response.statusText}
- HTTP error: ${response.status}
- HTTP ${response.status}
- HTTP ${response.status}
- HTTP ${response.status}: ${response.statusText}
AI-assisted analysis of sickn33/agentic-awesome-skills@58d857988f (2026-08-26).
Data as JSON: /api/errors/c490fd511a07c717.
Report an issue: GitHub.