# How to Debug LangExtract Extraction Issues Using Debug Mode

> Debug LangExtract extraction issues efficiently using debug mode. Enable debug=True in langextract.extraction.extract() for detailed pipeline logging and insight into tokenization, resolution, and LLM calls.

- Repository: [Google/langextract](https://github.com/google/langextract)
- Tags: how-to-guide
- Published: 2026-02-19

---

**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`](https://github.com/google/langextract/blob/main/langextract/extraction.py#L94-L99)). This attaches a `StreamHandler` to the `"langextract"` logger, sets the level to `DEBUG`, and raises `absl.logging` verbosity (implementation: [`debug_utils.py:151-179`](https://github.com/google/langextract/blob/main/langextract/core/debug_utils.py#L151-L179)).

### 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`](https://github.com/google/langextract/blob/main/langextract/core/debug_utils.py#L34-L44)). 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`](https://github.com/google/langextract/blob/main/langextract/core/debug_utils.py#L6-L48)) 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)](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`](https://github.com/google/langextract/blob/main/resolver.py), [`annotation.py`](https://github.com/google/langextract/blob/main/annotation.py), and [`chunking.py`](https://github.com/google/langextract/blob/main/chunking.py) emit native `logging.debug()` statements under the `"langextract.debug"` logger. For example, [`resolver.py`](https://github.com/google/langextract/blob/main/resolver.py) contains debug statements around lines 254-275 and 315-346 that trace alignment decisions, while [`annotation.py`](https://github.com/google/langextract/blob/main/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:

```python
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:

```python
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`](https://github.com/google/langextract/blob/main/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:

```python
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`](https://github.com/google/langextract/blob/main/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`](https://github.com/google/langextract/blob/main/resolver.py) (alignment logic), [`annotation.py`](https://github.com/google/langextract/blob/main/annotation.py) (chunk handling), and [`core/tokenizer.py`](https://github.com/google/langextract/blob/main/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`](https://github.com/google/langextract/blob/main/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`](https://github.com/google/langextract/blob/main/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`](https://github.com/google/langextract/blob/main/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.