{"record":{"id":"e24929eab8a537ac","repo":"PaddlePaddle/PaddleOCR","slug":"authentication-failed-text","errorCode":null,"errorMessage":"Authentication failed: ${text}","messagePattern":"Authentication failed: (.+?)","errorType":"exception","errorClass":"AuthError","httpStatus":401,"severity":"critical","filePath":"api_sdk/typescript/src/internal/http.ts","lineNumber":237,"sourceCode":"      }\n      const message = e instanceof Error ? e.message : String(e);\n      throw new NetworkError(`Connection failed: ${message}`);\n    } finally {\n      clearTimeout(timeoutID);\n      signal?.removeEventListener(\"abort\", abort);\n    }\n\n    if (resp.ok) return resp;\n\n    let text = await resp.text();\n    try {\n      const payload = JSON.parse(text) as { msg?: string; message?: string; errorMsg?: string };\n      text = payload.msg || payload.message || payload.errorMsg || text;\n    } catch {\n      // Keep raw response text.\n    }\n    if (resp.status === 401 || resp.status === 403) {\n      throw new AuthError(`Authentication failed: ${text}`);\n    } else if (resp.status === 400) {\n      throw new InvalidRequestError(`Bad request: ${text}`);\n    } else if (resp.status === 429) {\n      throw new RateLimitError(`Rate limit exceeded: ${text}`);\n    } else if (resp.status === 503 || resp.status === 504) {\n      throw new ServiceUnavailableError(resp.status, `Service unavailable: ${text}`);\n    } else {\n      throw new APIError(resp.status, text);\n    }\n  }\n}\n\nfunction requireJobId(data: SubmitResponse): string {\n  if (!data || typeof data.jobId !== \"string\" || data.jobId.length === 0) {\n    throw new ResponseFormatError(\"Submit response is missing jobId.\");\n  }\n  return data.jobId;\n}","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/api_sdk/typescript/src/internal/http.ts#L219-L255","documentation":"AuthError is thrown when the API answers HTTP 401 or 403. The message embeds the server's explanation (extracted from the body's msg/message/errorMsg field when present, else the raw text). It means the request reached the server but the credentials were rejected or lack permission for the operation.","triggerScenarios":"Calling any authenticated method with an expired, malformed, or revoked API key/token; using a key from one environment against another (test vs prod); a token with scopes that do not cover the requested endpoint; a key that was rotated server-side while still cached in a long-lived client instance.","commonSituations":"Hardcoded keys rotated by a security policy; tokens expired because the clock drifted or the session TTL passed; environment variables not set in the deployment (empty-string key); free-tier keys hitting a paid-only endpoint; copying examples with placeholder keys.","solutions":["Check the key is present and non-empty in the environment where the code actually runs (print its length/prefix, never the value)","Regenerate or refresh the API key/token and update configuration","Confirm the key matches the environment and has the required permissions/scopes for the endpoint you call","For long-running processes, build a fresh client after key rotation instead of reusing an instance holding old credentials"],"exampleFix":"try {\n  const jobId = await client.submitJson(model, payload);\n} catch (e) {\n  if (e instanceof AuthError) {\n    // re-create client with refreshed credentials and retry once\n    const fresh = createClient({ apiKey: await loadFreshToken() });\n    return fresh.submitJson(model, payload);\n  }\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":"function hasUsableKey(key: string | undefined): boolean {\n  return typeof key === \"string\" && key.trim().length >= 20;\n}","typeGuard":"function isAuthError(e: unknown): e is AuthError {\n  return e instanceof AuthError;\n}","tryCatchPattern":"try {\n  await client.submitJson(model, payload);\n} catch (e) {\n  if (e instanceof AuthError) {\n    // do NOT retry with the same key: refresh credentials, rebuild client, retry once\n    const freshClient = createClient({ apiKey: await refreshCredentials() });\n    return freshClient.submitJson(model, payload);\n  }\n  throw e;\n}","preventionTips":["Validate key presence and rough shape at client construction time","Load credentials from a secret manager (never hardcode); rotate before expiry","Build a new client instance after key rotation rather than reusing long-lived ones"],"tags":["authentication","http","credentials","typescript"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}