How to Debug LangExtract Extraction Issues Using Debug Mode

Enable the debug=True parameter in langextract.extraction.extract() to activate detailed logging across the entire pipeline, automatically redacting sensitive credentials while tracing tokenization, resolution, and LLM calls.

When extractions return empty results or alignment fails silently in the google/langextract library, pinpointing the failure point requires visibility into the internal pipeline. The library provides a built-in debug mode that instruments every major component—from tokenizers to the resolver—without exposing API keys or passwords in logs.

How LangExtract Debug Mode Instruments the Pipeline

Debug Logger Configuration

When you pass debug=True to extraction.extract(), the function invokes langextract.core.debug_utils.configure_debug_logging() (source: langextract/extraction.py:94-99). This attaches a StreamHandler to the "langextract" logger, sets the level to DEBUG, and raises absl.logging verbosity (implementation: debug_utils.py:151-179).

Automatic Credential Redaction

All logged arguments pass through _redact_mapping and _redact_value functions that scan for sensitive keys defined in _REDACT_KEYS_ (e.g., api_key, token, password) and replace their values with <REDACTED> (source: debug_utils.py:34-44). This ensures secrets never appear in debug output.

Function Call Tracing with Decorators

Core components use the @debug_log_calls decorator (implementation: debug_utils.py:6-48) to automatically log:

  • CALL: Function name and safe argument representation
  • RETURN: Truncated result and execution time in milliseconds
  • EXCEPTION: Error details with timing

Decorated functions include RegexTokenizer.tokenize and UnicodeTokenizer.tokenize in [langextract/core/tokenizer.py](https://github.com/google/langextract/blob/main/langextract/core/tokenizer.py), as well as resolver and chunking methods.

Per-Module Debug Output

Modules like resolver.py, annotation.py, and chunking.py emit native logging.debug() statements under the "langextract.debug" logger. For example, resolver.py contains debug statements around lines 254-275 and 315-346 that trace alignment decisions, while annotation.py logs chunk boundaries and timing (lines 205-306, 570-600).

How to Enable Debug Mode

Single Extraction Call

Pass debug=True to the extract() function:

from langextract import extraction

result = extraction.extract(
    text_or_documents="Your input text here",
    prompt_description="Extract entities:",
    examples=[...],
    debug=True,                # Enable verbose logging

    show_progress=False,       # Optional: suppress progress bar for cleaner output

)

Global Debug Configuration

Enable debugging for multiple calls without repeating the flag:

from langextract.core import debug_utils

debug_utils.configure_debug_logging()

# All subsequent extract() calls will emit debug logs

doc1 = extraction.extract(...)
doc2 = extraction.extract(...)

Diagnosing LangExtract Extraction Issues from Debug Logs

When debug=True, the console displays structured logs:


2026-02-19 12:34:56,789 - langextract - DEBUG - [langextract.core.tokenizer] CALL: RegexTokenizer.tokenize(text='Lorem ipsum...')
2026-02-19 12:34:56,800 - langextract - DEBUG - [langextract.core.tokenizer] RETURN: TokenizedText(tokens=[...]) (10.2 ms)
2026-02-19 12:34:57,015 - langextract - DEBUG - [langextract.resolver] CALL: Resolver.resolve(...)

Use these logs to:

  • Verify tokenizer selection: Confirm whether RegexTokenizer or UnicodeTokenizer processed your text
  • Inspect token boundaries: Check the intermediate TokenizedText tokens list for correct segmentation
  • Trace resolver alignment: Review resolver.py debug output (lines 254-275, 315-346, 410-463) to verify how chunks align with source text
  • Identify performance bottlenecks: Compare timestamps between CALL and RETURN entries to measure time spent in tokenization, resolution, or provider API calls

Capturing Debug Logs Programmatically

To store logs in a file instead of stdout, configure a file handler before extraction:

import logging
from langextract.core import debug_utils

handler = logging.FileHandler("debug_output.log")
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
handler.setFormatter(formatter)

logging.getLogger("langextract").addHandler(handler)
debug_utils.configure_debug_logging()

# Extraction output saved to file

doc = extraction.extract(
    "Sample text …",
    prompt_description="…",
    examples=examples,
)

Summary

  • Enable debug mode by passing debug=True to extraction.extract() or calling debug_utils.configure_debug_logging() globally.
  • Sensitive data is automatically redacted via _REDACT_KEYS_ filtering in debug_utils.py, replacing credentials with <REDACTED>.
  • The @debug_log_calls decorator instruments core functions including tokenizers and the resolver, logging entry points, return values, timing, and exceptions.
  • Key files emitting debug information include resolver.py (alignment logic), annotation.py (chunk handling), and core/tokenizer.py (tokenization).
  • Use show_progress=False to eliminate progress bar noise when reading debug logs.

Frequently Asked Questions

How do I enable debug mode for all LangExtract calls in my script?

Call debug_utils.configure_debug_logging() once at the start of your script. This configures the root "langextract" logger to DEBUG level, causing all subsequent extraction.extract() calls to emit detailed logs regardless of the debug parameter value.

Why don't I see my API key in the debug logs?

The debug system automatically redacts sensitive values. Keys matching the _REDACT_KEYS_ set—including api_key, token, and password—are replaced with <REDACTED> by the _redact_mapping and _redact_value functions in langextract/core/debug_utils.py before logging.

What should I check if my extraction returns empty results?

Enable debug mode and examine the resolver.py logs around lines 254-275. Look for debug statements showing the extraction_data input to the resolver; if this data is empty or malformed, the issue occurs upstream in tokenization or chunking (check annotation.py logs at lines 205-306).

How can I measure which step is slowing down my extraction?

Analyze the timestamps between CALL and RETURN entries in the debug output. The @debug_log_calls decorator records execution time for each instrumented function, allowing you to compare durations across tokenization (RegexTokenizer.tokenize or UnicodeTokenizer.tokenize), resolution (Resolver.resolve), and LLM provider calls.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →