HKUDS/DeepTutor · error · ValueError

ConceptAnalysisAgent prompts are not configured.

Error message

ConceptAnalysisAgent prompts are not configured.

What it means

Raised when pypdf raises FileNotDecryptedError while reading pages of an encrypted PDF whose is_encrypted flag did not already trip the earlier check (e.g. a PDF decrypted with a wrong/owner password where page access still fails). The original exception is chained and wrapped in CorruptDocumentError.

Source

Thrown at deeptutor/agents/math_animator/agents/concept_analysis_agent.py:55

        style_hint: str,
        attachments: list[Attachment],
    ) -> ConceptAnalysis:
        system_prompt = self.get_prompt("system")
        user_template = self.get_prompt("user_template")
        if not system_prompt or not user_template:
            # Retry once: a worker that looked the prompts up before the
            # package finished installing used to cache the empty result
            # forever. PromptManager no longer caches misses, so a reload can
            # now actually recover — and it stays the one place that knows how
            # to find a prompt file.
            self.prompts = get_prompt_manager().reload_prompts(
                "math_animator", "concept_analysis_agent", self.language
            )
            system_prompt = self.get_prompt("system")
            user_template = self.get_prompt("user_template")

        if not system_prompt or not user_template:
            raise ValueError("ConceptAnalysisAgent prompts are not configured.")

        reference_count = sum(1 for item in attachments if item.type == "image")
        user_prompt = user_template.format(
            user_input=user_input.strip(),
            history_context=history_context.strip() or "(none)",
            output_mode=output_mode,
            style_hint=style_hint.strip() or "(none)",
            reference_count=reference_count,
        )
        messages = [
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": user_prompt},
        ]
        _chunks: list[str] = []
        async for _c in self.stream_llm(
            user_prompt=user_prompt,
            system_prompt=system_prompt,
            messages=messages,

View on GitHub (pinned to 3e82f13042)

Solutions

  1. Decrypt properly with pikepdf/qpdf upstream
  2. Upgrade pypdf — decryption behavior has changed across versions
  3. Fall back to pymupdf (install it), which handles more encryption edge cases

Example fix

// before
text = extract_text_from_bytes(data, filename="weird.pdf")

// after
import pikepdf, io
with pikepdf.open(io.BytesIO(data)) as pdf:  # normalizes encryption edge cases
    buf = io.BytesIO(); pdf.save(buf)
text = extract_text_from_bytes(buf.getvalue(), filename="weird.pdf")
Defensive patterns

Strategy: fallback

Validate before calling

import pikepdf, io

def normalize_pdf(data: bytes) -> bytes:
    try:
        with pikepdf.open(io.BytesIO(data)) as pdf:
            buf = io.BytesIO(); pdf.save(buf); return buf.getvalue()
    except pikepdf.PasswordError:
        raise ValueError("password required")
    except Exception:
        return data

Try / catch

except CorruptDocumentError as e:
    if "encrypted" in str(e):
        data2 = normalize_pdf(data)  # best-effort repair
        text = extract_text_from_bytes(data2, filename=fn)

Prevention

When it happens

Trigger: pypdf opens the file but page.extract_text() raises FileNotDecryptedError on an encrypted PDF where is_encrypted was false or decrypt partially succeeded.

Common situations: Edge-case encrypted PDFs (owner-password-only, broken encryption dictionaries) in ingestion pipelines; version drift in pypdf changing when FileNotDecryptedError is emitted.

Related errors


AI-assisted analysis of HKUDS/DeepTutor@3e82f13042 (2026-08-27). Data as JSON: /api/errors/2c21b61f66217f52. Report an issue: GitHub.