ruvnet/ruflo · error · OAuthError
network
network
Error message
network error: ${e instanceof Error ? e.message : String(e)} What it means
postForm wraps fetch for POST /oauth/token; any thrown fetch exception (DNS failure, ECONNREFUSED, TLS error, proxy refusal) is normalized to OAuthError code 'network' carrying the underlying message. The request never got an HTTP response — this is transport-level failure, not an OAuth decision.
Source
Thrown at v3/@claude-flow/security/src/oauth/client.ts:101
body.error,
body.error_description,
);
} catch (e) {
if (e instanceof OAuthError) throw e;
throw new OAuthError('unexpected response shape from the server', 'unexpected_shape');
}
}
async function postForm(path: string, form: Record<string, string>, base = authBaseUrl()): Promise<TokenResponse> {
let resp: Response;
try {
resp = await fetch(`${base}${path}`, {
method: 'POST',
headers: { 'content-type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams(form).toString(),
});
} catch (e) {
throw new OAuthError(`network error: ${e instanceof Error ? e.message : String(e)}`, 'network');
}
return parseTokenResponse(resp);
}
/** `POST /oauth/token` with `grant_type=authorization_code`. */
export async function exchangeCode(
code: string,
codeVerifier: string,
redirectUri: string,
base = authBaseUrl(),
): Promise<TokenResponse> {
return postForm(
'/oauth/token',
{ grant_type: 'authorization_code', code, code_verifier: codeVerifier, client_id: CLIENT_ID, redirect_uri: redirectUri },
base,
);
}
View on GitHub (pinned to fa13ee4ad6)
Solutions
- Check reachability: curl -v https://auth.cognitum.one/oauth/token — any HTTP status (even 4xx) means transport is fine
- Set HTTPS_PROXY/HTTP_PROXY (and NO_PROXY where needed) on proxied networks
- For private CAs: export NODE_EXTRA_CA_CERTS=/path/to/ca.pem
- Retry with backoff — transport failures are frequently transient
Example fix
# before: CI runner with no direct egress # → network error: fetch failed # after export HTTPS_PROXY=http://proxy.corp:3128 export NO_PROXY=localhost,127.0.0.1
Defensive patterns
Strategy: retry
Validate before calling
async function authHostReachable(base: string): Promise<boolean> {
try {
await fetch(base, { method: 'HEAD' });
return true; // any response means transport works
} catch {
return false;
}
}
if (!(await authHostReachable(process.env.COGNITUM_AUTH_URL ?? 'https://auth.cognitum.one'))) {
throw new Error('auth host unreachable — check network/proxy config');
} Type guard
function isOAuthNetworkError(e: unknown): boolean {
return e instanceof Error && e.name === 'OAuthError' && (e as { code?: string }).code === 'network';
} Try / catch
for (let attempt = 1; attempt <= 3; attempt++) {
try {
return await exchangeCode(code, verifier, redirectUri);
} catch (e) {
if (isOAuthNetworkError(e) && attempt < 3) {
await new Promise((r) => setTimeout(r, 500 * 2 ** attempt));
continue;
}
throw e;
}
} Prevention
- Configure HTTPS_PROXY/NO_PROXY explicitly in restricted network environments
- Set NODE_EXTRA_CA_CERTS for private CAs instead of disabling TLS verification
- Wrap token requests in bounded retry with backoff — but never retry non-idempotent code exchanges without exactly-once protection
When it happens
Trigger: No DNS/route to auth.cognitum.one (offline sandbox); corporate network requiring HTTPS_PROXY that isn't set; COGNITUM_AUTH_URL pointing at an internal host with a self-signed cert Node doesn't trust; IPv6-only resolution breakage.
Common situations: CI jobs with no egress; forgotten proxy env vars on dev machines; private CAs missing from the Node trust store; transient DNS flakes on cloud runners.
Related errors
- HTTP transport failed: ${firstError instanceof Error ? first
- Resolved IP for ${hostname} is internal (${address})
- Could not reach the Cognitum auth service. ruflo core functi
- unexpected_shape
- Invalid hostname
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/72b0f0597b856b4e.
Report an issue: GitHub.