{"record":{"id":"06a97cb6cfa69ae8","repo":"HKUDS/DeepTutor","slug":"unable-to-reach-the-model-provider-please-retry","errorCode":null,"errorMessage":"Unable to reach the model provider. Please retry.","messagePattern":"Unable to reach the model provider\\. Please retry\\.","errorType":"exception","errorClass":"LLMProviderTransportError","httpStatus":null,"severity":"error","filePath":"deeptutor/agents/chat/agent_loop.py","lineNumber":787,"sourceCode":"                            \"error_code\": \"provider_transport\",\n                            \"retryable\": True,\n                            \"partial_response\": partial_response,\n                        },\n                    ),\n                )\n                message = self.pipeline._t(\n                    (\n                        \"notices.provider_stream_interrupted\"\n                        if partial_response\n                        else \"notices.provider_unavailable\"\n                    ),\n                    default=(\n                        \"The model provider interrupted this response. Please retry.\"\n                        if partial_response\n                        else \"Unable to reach the model provider. Please retry.\"\n                    ),\n                )\n                raise LLMProviderTransportError(\n                    message,\n                    partial_response=partial_response,\n                ) from exc\n            finally:\n                close = getattr(response_stream, \"close\", None)\n                if callable(close):\n                    with suppress(Exception):\n                        await close()\n            break\n\n        dsml_tail = dsml_filter.flush()\n        if dsml_tail:\n            await _emit_segments(think_filter.feed(dsml_tail))\n        await _emit_segments(think_filter.flush())\n        text = \"\".join(text_parts)\n        record_streamed_usage(\n            self.pipeline.usage,\n            usage_seen,","sourceCodeStart":769,"sourceCodeEnd":805,"githubUrl":"https://github.com/HKUDS/DeepTutor/blob/3e82f130422a813cdd73c10b21a44e9325f5821a/deeptutor/agents/chat/agent_loop.py#L769-L805","documentation":"Raised by the PyMuPDF (fitz) branch of _extract_pdf when the PDF is encrypted and cannot be opened with an empty password (doc.authenticate(\"\") fails). Password-protected PDFs cannot be text-extracted without credentials, so a CorruptDocumentError is raised with the filename attached.","triggerScenarios":"Extracting a PDF with an owner password (restrictions) where authenticate(\"\") returns 0; extracting a user-password-protected PDF via extract_text_from_bytes(data, filename='secret.pdf').","commonSituations":"Ingesting publisher-provided or DRM-ish ebooks, confidential documents, or PDFs exported with 'require password to open' options into a knowledge base.","solutions":["Decrypt the PDF upstream (qpdf --decrypt in.pdf out.pdf) before ingestion","Ask the uploader for the password, decrypt with pikepdf/pymupdf, then extract","Catch CorruptDocumentError and report 'encrypted PDF' to the user / skip the file"],"exampleFix":"// before\ntext = _extract_pdf(data, \"protected.pdf\")\n\n// after\nimport pikepdf\nwith pikepdf.open(io.BytesIO(data), password=pw) as pdf:\n    buf = io.BytesIO()\n    pdf.save(buf)\ntext = _extract_pdf(buf.getvalue(), \"protected.pdf\")","handlingStrategy":"try-catch","validationCode":"import fitz\ntry:\n    with fitz.open(stream=data, filetype=\"pdf\") as doc:\n        encrypted = doc.needs_pass\nexcept Exception:\n    encrypted = False\nif encrypted:\n    request_password_from_user()","typeGuard":null,"tryCatchPattern":"from deeptutor.utils.document_extractor import CorruptDocumentError\ntry:\n    text = extract_text_from_bytes(data, filename=fn)\nexcept CorruptDocumentError as e:\n    if \"encrypted\" in str(e):\n        prompt_for_password(fn)  # then decrypt & retry","preventionTips":["Pre-decrypt with qpdf --decrypt in the ingestion pre-processing step","Flag encrypted PDFs at upload time via a quick fitz.needs_pass probe"],"tags":["pdf","encryption","pymupdf","document-extraction"],"backgroundTag":"encrypted-pdf-password","analyzedSha":"3e82f130422a813cdd73c10b21a44e9325f5821a","analyzedAt":"2026-08-27T06:57:25.364Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}