{"record":{"id":"c3a41b4ef0223f82","repo":"PaddlePaddle/PaddleOCR","slug":"detection-model-session-is-not-initialized","errorCode":null,"errorMessage":"Detection model session is not initialized.","messagePattern":"Detection model session is not initialized\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"paddleocr-js/packages/core/src/models/det.ts","lineNumber":221,"sourceCode":"    boxThresh: config.postprocess.boxThresh,\n    unclipRatio: config.postprocess.unclipRatio\n  };\n  let sessionState: SessionState | null = await createDetModelSession(\n    ort,\n    modelBytes,\n    backend,\n    webgpuState\n  );\n\n  return {\n    kind: \"det\",\n    config,\n    get provider() {\n      return sessionState?.provider || \"\";\n    },\n    async predict(cv, mats, overrides) {\n      if (!sessionState?.session) {\n        throw new Error(\"Detection model session is not initialized.\");\n      }\n      const params = resolveDetParams(defaultParams, overrides);\n      const batchSize = resolveRuntimeBatchSize(overrides?.batchSize, defaultBatchSize);\n      const results: DetResult[] = [];\n      const runCtx: DetRunContext = {\n        cv,\n        ort,\n        config,\n        session: sessionState.session\n      };\n      for (const chunk of chunkArray(mats, batchSize)) {\n        const preps = preprocess({ cv, ort, config }, chunk, params);\n        const inputTensor = packDetBatchTensor(ort, preps);\n        const fullOutput = await runInference(sessionState.session, inputTensor);\n        const internals = postprocess(runCtx, fullOutput, preps, params);\n        for (const internal of internals) {\n          results.push({\n            boxes: internal.boxes,","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/PaddlePaddle/PaddleOCR/blob/2661c7c0ef5c613e8f93c6e93b2e052399f0f854/paddleocr-js/packages/core/src/models/det.ts#L203-L239","documentation":"Thrown by the detection model's predict() when the ONNX Runtime session was never created. createDetModel() returns a model object whose session is populated asynchronously (or during an initialize step); calling predict() before that completes — or after session creation failed — hits this guard. The getter provider returning \"\" is the observable symptom of the same uninitialized state.","triggerScenarios":"Calling detModel.predict(...) immediately after createDetModel() without awaiting the load/initialize routine that assigns sessionState.session; session creation threw earlier and the error was swallowed; model disposed/reset then reused.","commonSituations":"Missing await on an async loadModel/create call; fire-and-forget initialization with .then() while a UI event triggers prediction first; WASM/WebGPU backend failing to build the session (e.g. model fetch 404) leaving sessionState null.","solutions":["Await the model loading/initialization step (whatever populates the session) before any predict() call","Check model.provider !== \"\" as a cheap readiness signal before predicting","Inspect initialization logs/network tab — a failed model download or backend error usually explains the null session","If initialization failed, re-run it and surface its error instead of proceeding to predict"],"exampleFix":"// before\nconst model = createDetModel(...); // session loads async\nconst boxes = await model.predict(cv, mats); // throws: session not initialized\n\n// after\nconst model = createDetModel(...);\nawait loadDetModelSession(model); // whatever call assigns sessionState.session\nif (!model.provider) throw new Error(\"det model failed to load\");\nconst boxes = await model.predict(cv, mats);","handlingStrategy":"validation","validationCode":"const ready = detModel.provider !== \"\";\nif (!ready) {\n  await ensureDetModelLoaded(detModel); // or your loader equivalent\n}","typeGuard":"function isDetModelReady(m: { provider: string }): boolean {\n  return m.provider !== \"\";\n}","tryCatchPattern":"try { await detModel.predict(cv, mats); } catch (e) {\n  if (e instanceof Error && /session is not initialized/.test(e.message)) {\n    await ensureDetModelLoaded(detModel); // then retry once\n  } else throw e;\n}","preventionTips":["Always await the model load call and keep the promise in a variable you can await again before predict","Gate prediction UI on model.provider becoming non-empty","Surface initialization errors instead of swallowing them; a null session is usually a swallowed load failure"],"tags":["paddleocr","onnxruntime","lifecycle","async-init","detection"],"backgroundTag":null,"analyzedSha":"2661c7c0ef5c613e8f93c6e93b2e052399f0f854","analyzedAt":"2026-08-14T20:17:30.180Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}