HKUDS/DeepTutor · error · GenerationFailure

prompt leak detected in generated code.

Error message

prompt leak detected in generated code.

What it means

The generated code contains `<think` / `</think` markup, i.e. chain-of-thought or reasoning leakage from reasoning-style models leaked into the `code` field. The block deliberately rejects it to keep published snippets clean.

Source

Thrown at deeptutor/book/blocks/code.py:96

            chapter_title=chapter_title,
            chapter_summary=chapter_summary or none_label,
            objectives_inline="; ".join(objectives) or none_label,
            intent=intent,
            language=language,
        )
        data = await llm_json(
            user_prompt=user_prompt,
            system_prompt=get_book_prompt(prompts, "system"),
            max_tokens=900,
            temperature=0.3,
            language=ctx.language,
        )

        code = str(data.get("code") or "").strip()
        if not code:
            raise GenerationFailure("LLM did not return any code.")
        if "<think" in code.lower() or "</think" in code.lower():
            raise GenerationFailure("prompt leak detected in generated code.")

        code_language = str(data.get("language") or language).strip() or language
        syntax_error = _syntax_error(code, code_language)
        if syntax_error:
            # A truncated or malformed snippet is worse than none: the reader
            # copies it, it fails, and nothing said it was never checked. Fail
            # the block so the compiler's retry path gets a second attempt.
            raise GenerationFailure(f"generated code does not parse: {syntax_error}")

        metadata = data.get("_metadata") if isinstance(data.get("_metadata"), dict) else {}
        return (
            {
                "language": code_language,
                "code": code,
                "explanation": str(data.get("explanation") or "").strip(),
                "intent": intent,
            },
            [],

View on GitHub (pinned to 3e82f13042)

Solutions

  1. Retry — many providers emit think tags only sporadically
  2. Configure the provider/model to strip or disable thinking output for this call
  3. Use a non-reasoning model for code block generation
  4. Post-process is intentionally NOT done here — the block treats leakage as a failure so the retry path gets a clean attempt
Defensive patterns

Strategy: retry

Type guard

def leaks_reasoning(code: str) -> bool:
    c = code.lower()
    return "<think" in c or "</think" in c

Try / catch

try:
    result = await code_gen._generate(ctx)
except GenerationFailure as e:
    if "prompt leak" in str(e):
        result = await code_gen._generate(ctx)
    else:
        raise

Prevention

When it happens

Trigger: Using a reasoning model (or a provider that emits think tags) for the code block; the model wraps its answer in `<think>…</think>` and the extraction didn't strip it, so the literal tags land in `code`.

Common situations: Switching the book pipeline's model to a reasoning-tuned endpoint; prompts that encourage step-by-step output; provider changes in how thinking is surfaced.

Related errors


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