wandb/openui · error · Error
Unexpected response ${req.status}: ${await req.text()}
Error message
Unexpected response ${req.status}: ${await req.text()} What it means
post() sends JSON to the backend (used by register and auth for the WebAuthn ceremony result) and expects 200. Any other status throws an Error with the status and raw body text, which the callers' catch blocks then interpret.
Source
Thrown at frontend/src/api/openui.ts:163
client_data_json: asBase64(clientDataJSON),
signature: asBase64(signature),
authenticator_data: asBase64(authenticatorData)
}
}
const req = await fetch(
`${API_HOST}/${create ? 'register' : 'auth'}/${encodeURIComponent(
username
)}`,
{
credentials: 'same-origin',
method: 'POST',
body: JSON.stringify(data),
headers: { 'content-type': 'application/json' }
}
)
if (req.status !== 200) {
throw new Error(`Unexpected response ${req.status}: ${await req.text()}`)
}
}
export async function register(username: string): Promise<boolean> {
try {
const publicKey = (await getPublicKey(
username,
true
)) as PublicKeyCredentialCreationOptions
console.log('registration response:', publicKey.user, typeof publicKey.user)
publicKey.user.id = asArrayBuffer(publicKey.user.id as unknown as string)
publicKey.challenge = asArrayBuffer(
publicKey.challenge as unknown as string
)
const creds = await navigator.credentials.create({ publicKey })
await post(username, creds as PublicKeyCredential, true)
return true
} catch (error) {View on GitHub (pinned to 42d7ab4ab6)
Solutions
- Check response text for known strings like 'User already exists' and map them to friendly UI states (register already does this).
- Ensure cookies/session persist across getPublicKey and post (credentials: 'same-origin' is required).
- Retry the flow from getPublicKey if the challenge expired.
- Wrap register/auth in try/catch and show the parsed reason to the user.
Example fix
// before
throw new Error(`Unexpected response ${req.status}: ${await req.text()}`)
// after
const text = await req.text()
throw new Error(`WebAuthn post failed (${req.status}): ${text.slice(0, 200)}`) Defensive patterns
Strategy: try-catch
Validate before calling
if (!credential || !credential.response) throw new Error('WebAuthn ceremony was cancelled or failed') Type guard
function isRegistrationResponse(c: unknown): c is PublicKeyCredential {
return typeof c === 'object' && c !== null && 'response' in (c as object)
} Try / catch
try {
return await register(username)
} catch (e) {
if (String(e).includes('User already exists')) return false
throw e
} Prevention
- Persist the session cookie across the whole ceremony
- Restart the flow (fresh options) if the challenge expired
- Map known server error strings to friendly UI messages
When it happens
Trigger: Non-200 from POSTing the WebAuthn attestation/assertion: credential rejected or already registered, invalid challenge (expired), or missing session cookie.
Common situations: Registering a username that already exists (server returns 4xx whose text contains 'User already exists'); stale WebAuthn challenge after a page reload; browser cancelled the ceremony.
Related errors
- Unexpected response ${r.status}: ${await r.text()}
- No credential ID found
- body.error.message
- Unkown error: ${String(error)}
- Login required to use OpenUI
AI-assisted analysis of wandb/openui@42d7ab4ab6 (2026-09-01).
Data as JSON: /api/errors/235dc97cb697b6c6.
Report an issue: GitHub.