{"record":{"id":"66394fa3cd331fd1","repo":"PaddlePaddle/PaddleOCR","slug":"file-not-found-path-66394f","errorCode":null,"errorMessage":"File not found: ${path}","messagePattern":"File not found: (.+?)","errorType":"exception","errorClass":"FileNotFoundError","httpStatus":null,"severity":"error","filePath":"api_sdk/typescript/src/internal/http.ts","lineNumber":92,"sourceCode":"    }\n    if (options.batchId !== undefined) {\n      body.batchId = options.batchId;\n    }\n    const data = await this.fetchJson<SubmitResponse>(this.jobsUrl, {\n      method: \"POST\",\n      headers: { \"Content-Type\": \"application/json\" },\n      body: JSON.stringify(body),\n    }, options.signal);\n    return requireJobId(data);\n  }\n\n  async submitFile(model: string, filePath: string, optionalPayload: object, options: SubmitOptions = {}): Promise<string> {\n    const fs = await import(\"fs\");\n    const path = await import(\"path\");\n\n    if (!fs.existsSync(filePath)) {\n      const { FileNotFoundError } = await import(\"../errors.js\");\n      throw new FileNotFoundError(filePath);\n    }\n\n    const form = new FormData();\n    form.append(\"model\", model);\n    form.append(\"optionalPayload\", JSON.stringify(optionalPayload));\n    if (options.pageRanges !== undefined) {\n      form.append(\"pageRanges\", options.pageRanges);\n    }\n    if (options.batchId !== undefined) {\n      form.append(\"batchId\", options.batchId);\n    }\n\n    const fileBuffer = fs.readFileSync(filePath);\n    const blob = new Blob([fileBuffer]);\n    form.append(\"file\", blob, path.basename(filePath));\n\n    const data = await this.fetchJson<SubmitResponse>(this.jobsUrl, {\n      method: \"POST\",","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/api_sdk/typescript/src/internal/http.ts#L74-L110","documentation":"FileNotFoundError is thrown by submitFile() in the HTTP client when the local file path you passed does not exist on disk (checked with fs.existsSync before any network call). It is a client-side pre-flight validation failure, so no request is ever sent to the PaddleOCR API. The error instance carries the offending path on its `path` property.","triggerScenarios":"Calling client.submitFile(model, filePath, payload) (directly or via a higher-level extract/predict helper) where filePath points to a missing file: wrong relative path (resolved against process.cwd(), not the script), typo, file deleted between selection and upload, or a path from user input that was never validated.","commonSituations":"Running the SDK from a different working directory so relative paths break; paths built with manual '/' concatenation on Windows; files staged by an upstream process that has not finished writing; CI runners where the asset directory was not checked out.","solutions":["Verify the path exists before calling submitFile: fs.existsSync(filePath) or fs.promises.access(filePath, fs.constants.R_OK)","If the path is relative, resolve it against a known anchor: path.resolve(__dirname, 'assets/doc.pdf') instead of relying on cwd","On Windows or cross-platform code, build paths with path.join()/path.resolve() rather than string concatenation","If the file comes from async user input, await its write/download to complete before submitting"],"exampleFix":"// before\nconst jobId = await client.submitFile(\"PP-StructureV3\", req.query.file, {});\n\n// after\nimport fs from \"node:fs\";\nconst filePath = path.resolve(uploadsDir, req.query.file);\nif (!fs.existsSync(filePath)) {\n  return res.status(400).send(`No such file: ${filePath}`);\n}\nconst jobId = await client.submitFile(\"PP-StructureV3\", filePath, {});","handlingStrategy":"validation","validationCode":"import fs from \"node:fs\";\nimport path from \"node:path\";\n\nfunction assertReadableFile(filePath: string): void {\n  const abs = path.resolve(filePath);\n  if (!fs.existsSync(abs)) throw new Error(`No such file: ${abs}`);\n  const stat = fs.statSync(abs);\n  if (!stat.isFile()) throw new Error(`Not a file: ${abs}`);\n}","typeGuard":"function isReadableFilePath(p: string): boolean {\n  try {\n    return fs.statSync(path.resolve(p)).isFile();\n  } catch {\n    return false;\n  }\n}","tryCatchPattern":"try {\n  await client.submitFile(model, filePath, payload);\n} catch (e) {\n  if (e instanceof FileNotFoundError) {\n    // client-side: fix path or regenerate the file, do not retry as-is\n    throw new Error(`Input missing: ${e.path}`);\n  }\n  throw e;\n}","preventionTips":["Resolve user-supplied paths with path.resolve against an explicit base directory, never process.cwd()","Validate file existence and readability at the API boundary before enqueueing work","If files arrive asynchronously, await the producing promise before submission"],"tags":["filesystem","validation","typescript","pre-flight"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}