{"record":{"id":"a90a798d133d19c6","repo":"PaddlePaddle/PaddleOCR","slug":"bad-request-text","errorCode":null,"errorMessage":"Bad request: ${text}","messagePattern":"Bad request: (.+?)","errorType":"exception","errorClass":"InvalidRequestError","httpStatus":400,"severity":"error","filePath":"api_sdk/typescript/src/internal/http.ts","lineNumber":239,"sourceCode":"      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}\n","sourceCodeStart":221,"sourceCodeEnd":256,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/api_sdk/typescript/src/internal/http.ts#L221-L256","documentation":"InvalidRequestError is thrown when the API answers HTTP 400, meaning the request itself is malformed or violates the API contract. The server's explanation (from the body's msg/message/errorMsg field, or raw text) is embedded in the message, so it tells you exactly which parameter was wrong.","triggerScenarios":"submitJson with a payload missing required fields or with wrong types; submitFile with an unsupported file extension, an oversized file, or invalid pageRanges format; batchId referencing a non-existent batch; passing model names the backend does not recognize.","commonSituations":"Schema drift between SDK version and API version; hand-built payloads copied from outdated docs; page ranges like \"5-\" or non-numeric input; file formats the service rejects; forgetting required fields when moving from curl examples to code.","solutions":["Read the embedded server message — it names the offending parameter","Validate payload shape against the current SDK types/README before submitting (TypeScript compiler errors catch most cases)","Check file constraints: supported formats, size limits, and pageRanges syntax","Upgrade the SDK so request building matches the current server-side schema"],"exampleFix":"try {\n  await client.submitFile(model, filePath, {}, { pageRanges });\n} catch (e) {\n  if (e instanceof InvalidRequestError) {\n    console.error(\"Server rejected request:\", e.message); // names the bad param\n  }\n}","handlingStrategy":"validation","validationCode":"const VALID_PAGE_RANGE = /^\\d+-\\d+$/;\nfunction validateSubmitOptions(opts: { pageRanges?: string; batchId?: string }): string[] {\n  const errs: string[] = [];\n  if (opts.pageRanges !== undefined && !VALID_PAGE_RANGE.test(opts.pageRanges)) {\n    errs.push(`pageRanges must match 'N-M', got '${opts.pageRanges}'`);\n  }\n  return errs;\n}","typeGuard":"function isInvalidRequestError(e: unknown): e is InvalidRequestError {\n  return e instanceof InvalidRequestError;\n}","tryCatchPattern":"try {\n  await client.submitFile(model, filePath, payload, opts);\n} catch (e) {\n  if (e instanceof InvalidRequestError) {\n    // permanent client error: surface e.message (names the bad param), never retry\n    throw new ValidationError(e.message);\n  }\n  throw e;\n}","preventionTips":["Validate pageRanges format, file extension, and required payload fields before calling the API","Let TypeScript type-check payloads at compile time; avoid `as any` escapes","Read the embedded server message on 400s and fix the named parameter rather than retrying"],"tags":["validation","http","bad-request","typescript"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}