hcengineering/platform · error · Error
HTTP error ${res.status}
Error message
HTTP error ${res.status} What it means
rpc in the collaborator client performs an HTTP POST to the collaborator service and throws a plain Error('HTTP error <status>') when the response is not ok. The status code is included, but the response body (which usually holds the real reason) is discarded.
Source
Thrown at foundations/core/packages/collaborator-client/src/client.ts:85
) {}
private async rpc<P, R>(document: CollaborativeDoc, method: string, payload: P): Promise<R> {
const workspace = this.workspace
const documentId = encodeDocumentId(workspace, document)
const url = concatLink(this.collaboratorUrl, `/rpc/${encodeURIComponent(documentId)}`)
const res = await fetch(url, {
method: 'POST',
headers: {
Authorization: 'Bearer ' + this.token,
'Content-Type': 'application/json'
},
body: JSON.stringify({ method, payload })
})
if (!res.ok) {
throw new Error('HTTP error ' + res.status)
}
const result = await res.json()
if (result.error != null) {
throw new Error(result.error)
}
return result as R
}
async getMarkup (document: CollaborativeDoc, source?: Ref<Blob> | null): Promise<Markup> {
const payload: GetContentRequest = {
source: source !== null ? source : undefined
}
const res = await retry(
3,View on GitHub (pinned to 63e28dc964)
Solutions
- Note the status in the message: 401/403 -> fix token; 404 -> check document/URL; 5xx -> retry with backoff.
- Verify the collaborator service URL in configuration.
- Refresh the auth token before the rpc call.
- Improve the error by reading res.text() before throwing, to capture the server's reason.
- Catch and map statuses to user-facing messages in the calling layer.
Example fix
// before
throw new Error('HTTP error ' + res.status)
// after
const body = await res.text()
throw new Error(`HTTP error ${res.status}: ${body}`) Defensive patterns
Strategy: retry
Validate before calling
// preflight connectivity
const ping = await fetch(collaboratorUrl, { method: 'HEAD' }).catch(() => null)
if (ping === null || !ping.ok) throw new Error('Collaborator service unreachable') Type guard
function isHttpError(err: unknown): err is Error & { status?: number } {
return err instanceof Error && /^HTTP error \d+$/.test(err.message)
} Try / catch
for (let attempt = 0; attempt < 3; attempt++) {
try {
return await client.rpc(method, payload)
} catch (err) {
const status = Number(err.message.split(' ').pop())
if (status >= 500 && attempt < 2) { await sleep(2 ** attempt * 500); continue }
throw err
}
} Prevention
- Verify the collaborator URL in configuration before deploying
- Refresh tokens proactively for long-lived sessions
- Retry only 5xx statuses; surface 4xx to the user
- Include response body in errors for diagnosability
When it happens
Trigger: Any rpc() call (directly or via res/updateMarkup) where the collaborator endpoint returns 401/403/404/5xx — bad URL, expired token, unknown document, or collaborator service outage.
Common situations: Collaborator service URL misconfigured; auth token missing/expired; requesting markup for a document that doesn't exist; collaborator service restarting or crashed.
Related errors
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/fe049ec5e5076697.
Report an issue: GitHub.