# Troubleshooting

> Common failure modes: missing API keys, vLLM `base_url` requirements, `--lang` required for knowledge templates, empty output directory conflicts, missing `data.json` or index for `search`/`talk`, template resolution errors, and debug logging via `HYPER_EXTRACT_LOG_LEVEL`.

- Repository: yifanfeng97/Hyper-Extract
- GitHub: https://github.com/yifanfeng97/Hyper-Extract
- Human docs: https://grok-wiki.com/public/docs/yifanfeng97-hyper-extract-7891c7254cdf
- Complete Markdown: https://grok-wiki.com/public/docs/yifanfeng97-hyper-extract-7891c7254cdf/llms-full.txt

## Source Files

- `hyperextract/cli/utils.py`
- `hyperextract/cli/config.py`
- `hyperextract/cli/cli.py`
- `hyperextract/utils/logging.py`
- `hyperextract/cli/README.md`
- `tests/cli/test_verbose.py`

---

---
title: "Troubleshooting"
description: "Common failure modes: missing API keys, vLLM `base_url` requirements, `--lang` required for knowledge templates, empty output directory conflicts, missing `data.json` or index for `search`/`talk`, template resolution errors, and debug logging via `HYPER_EXTRACT_LOG_LEVEL`."
---

Hyper-Extract surfaces most CLI failures as `Error:` messages on stderr and exits with code `1`. Commands that call LLM or embedder clients (`he parse`, `he feed`, `he search`, `he talk`, `he show`, `he build-index`) run `validate_config()` first; Knowledge Abstract (KA) commands additionally validate directory layout via `validate_ka_path`, `validate_ka_with_data`, or `validate_ka_with_index` in `hyperextract/cli/utils.py`.

## Quick diagnosis

| Symptom | Likely cause | First fix |
|---------|--------------|-----------|
| `LLM API key is not configured` | Missing `[llm]` key and no `OPENAI_API_KEY` | `he config init -k YOUR_KEY` |
| `vLLM provider requires base_url` | `provider = "vllm"` without URL | `he config llm -p vllm -u http://localhost:8000/v1` |
| `--lang is required for knowledge templates` | Domain template without `-l` | Add `--lang en` or `--lang zh` |
| `Output directory already exists and is not empty` | Reusing a populated `-o` path | `-f` or pick a new directory |
| `no data.json` | Path is not a valid KA | Run `he parse` or point at the KA root |
| `Index not found` | `he parse --no-index` or never built index | `he build-index <ka_path>` |
| `Template '…' not found` | Wrong template ID or missing local YAML | `he list template` |
| No stage logs during extraction | Default log level is `WARNING` | `export HYPER_EXTRACT_LOG_LEVEL=DEBUG` |

<Info>
`he info <ka_path>` reports whether `data.json` exists and whether `index/` is populated. Use it before `he search` or `he talk`.
</Info>

## Configuration failures

### Missing API keys

`validate_config()` in `hyperextract/cli/config.py` checks both LLM and embedder credentials before any network call.

For non-vLLM providers, an empty API key triggers:

```text
Error: LLM API key is not configured. Run 'he config llm --api-key YOUR_KEY'
```

or the equivalent embedder message.

<Steps>
<Step title="Configure credentials">

```bash
he config init -k YOUR_API_KEY
```

Or set per service:

```bash
he config llm --api-key YOUR_KEY --model gpt-4o-mini
he config embedder --api-key YOUR_KEY --model text-embedding-3-small
```

</Step>
<Step title="Verify">

```bash
he config show
```

Keys resolve from `~/.he/config.toml` first, then fall back to `OPENAI_API_KEY` and `OPENAI_BASE_URL`.

</Step>
</Steps>

<ParamField body="OPENAI_API_KEY" type="string">
API key used when `[llm].api_key` or `[embedder].api_key` is empty in `~/.he/config.toml`.
</ParamField>

<ParamField body="OPENAI_BASE_URL" type="string">
Optional override for `[llm].base_url` and `[embedder].base_url` when not set in config.
</ParamField>

### vLLM `base_url` requirements

The `vllm` provider preset sets `base_url`, `default_llm`, and `default_embedder` to `None`. Hyper-Extract never infers a local endpoint—you must supply URLs explicitly.

Validation errors:

```text
Error: vLLM provider requires base_url.
Error: vLLM embedder requires base_url.
```

If `provider` is `vllm` (or any preset with `base_url: None`) and no URL is in config or `OPENAI_BASE_URL`, `_resolve_base_url` raises:

```text
Provider 'vllm' requires explicit base_url. Please set it via config or environment variable.
```

<CodeGroup>
```bash title="CLI — separate LLM and embedder endpoints"
he config llm -p vllm -m Qwen3.5-9B -u http://localhost:8000/v1 -k dummy
he config embedder -p vllm -m bge-m3 -u http://localhost:8001/v1 -k dummy
```

```bash title="Environment variable"
export OPENAI_BASE_URL=http://localhost:8000/v1
```

```toml title="~/.he/config.toml"
[llm]
provider = "vllm"
model = "Qwen3.5-9B"
api_key = "dummy"
base_url = "http://localhost:8000/v1"

[embedder]
provider = "vllm"
model = "bge-m3"
api_key = "dummy"
base_url = "http://localhost:8001/v1"
```
</CodeGroup>

<Warning>
`he config init -p vllm -k dummy` without `-u` saves vLLM credentials but leaves `base_url` empty. The next `he parse` fails at `validate_config()`. Always pass `--base-url` for vLLM quick init, or complete interactive setup and enter URLs when prompted.
</Warning>

<Tip>
Interactive `he config init` accepts `dummy` as the API key for vLLM and prompts separately for LLM and embedder base URLs (for example `http://localhost:8000/v1` and `http://localhost:8001/v1`).
</Tip>

## Parse and extraction failures

### `--lang` required for knowledge templates

Domain YAML templates (`general/biography_graph`, `finance/earnings_summary`, etc.) require a language because `TemplateFactory.create` calls `localize_template` with the supplied code.

CLI guard (knowledge templates only):

```text
Error: --lang is required for knowledge templates. Use --lang en or --lang zh.
```

Python API equivalent:

```text
ValueError: language is required for knowledge templates. Provide a language code (e.g., 'zh', 'en').
```

<RequestExample>
```bash
# Knowledge template — -l required
he parse document.md -t general/biography_graph -o ./out/ -l en

# Method template — -l optional (forced to en)
he parse document.md -m light_rag -o ./out/
```
</RequestExample>

Method templates (`method/light_rag`, `-m hyper_rag`, etc.) always use English prompts. If you pass `--lang`, the CLI prints a dim note and ignores it.

### Empty output directory conflicts

`he parse` refuses to write into a non-empty output directory unless `--force` is set:

```text
Error: Output directory already exists and is not empty. Use --force to overwrite.
```

An existing but **empty** directory is allowed. Use `-f` / `--force` to overwrite populated KA artifacts (`data.json`, `metadata.json`, `index/`).

### Template resolution errors

Template lookup happens at two stages: config resolution (`Template.get`) before extraction, and instance creation (`Template.create` → `TemplateFactory.create`).

| Error | When | Fix |
|-------|------|-----|
| `Template 'xxx' not found` | Preset ID not in gallery and not a `.yaml` path | `he list template` or `he list template -q keyword` |
| `Template not found: {source}` | Python `Template.create` with invalid path | Confirm spelling; use full preset path like `general/biography_graph` |
| `Config file not found: {file_path}` | Custom YAML path missing | Check file path and permissions |
| `Template '…' not found in presets and local file '…yaml' does not exist` | Reloading KA whose template left the gallery | Copy `{template}.yaml` into the KA directory or re-parse with a current preset |

<Steps>
<Step title="List presets">

```bash
he list template
he list template -l zh -q finance
```

</Step>
<Step title="Resolve at parse time">

```bash
he parse doc.md -t general/biography_graph -o ./ka/ -l en
```

Omit `-t` for interactive selection when unsure of the ID.

</Step>
<Step title="Resolve when reloading a KA">

`he show`, `he search`, `he talk`, and `he build-index` read `metadata.json` and resolve the template via `get_template_from_ka`: preset name first, then `{ka_path}/{template}.yaml`.

</Step>
</Steps>

### Other parse input errors

```text
Error: No .txt or .md files found in {input}
```

Directory inputs only include `*.txt` and `*.md` files. Other extensions are skipped.

```text
Input file not found: {input_path}
```

Check the path or use `-` for stdin.

## Knowledge Abstract validation

A valid KA directory contains at minimum `data.json` and `metadata.json`. Semantic search and chat additionally require a non-empty `index/` subdirectory.

:::files
```
my_ka/
├── data.json        # extracted knowledge (required for most commands)
├── metadata.json    # template, lang, timestamps (required for feed/reload)
└── index/           # vector index (required for search/talk)
    └── …
:::
```

### Missing `data.json`

Commands using `validate_ka_with_data` (`he info`, `he show`, `he build-index`):

```text
Error: Not a valid Knowledge Abstract: {ka_path} (no data.json)
```

`he feed` only requires `metadata.json` at the KA root; it loads existing data via `ka.load()` and will fail later if `data.json` is absent.

### Missing index for `search` and `talk`

Both commands call `validate_ka_with_index`:

```text
Error: Index not found. Please run 'he build-index {ka_path}' first.
```

Common causes:

- `he parse … --no-index` skipped index creation
- `he feed` appended data without rebuilding the index
- `index/` exists but is empty

<Steps>
<Step title="Build or rebuild the index">

```bash
he build-index ./my_ka/
he build-index ./my_ka/ --force   # replace existing index
```

</Step>
<Step title="Confirm readiness">

```bash
he info ./my_ka/
# Index row should show: Built
```

</Step>
<Step title="Query">

```bash
he search ./my_ka/ "your query"
he talk ./my_ka/ -q "your question"
he talk ./my_ka/ -i
```

</Step>
</Steps>

<Note>
`he build-index` exits `0` with a warning when an index already exists and `--force` is not passed—it does not rebuild silently. Pass `-f` to force a rebuild.
</Note>

### Metadata and template reload failures

| Error | Command | Fix |
|-------|---------|-----|
| `Knowledge Abstract not found` | Any KA command | Check path |
| `Not a directory` | Any KA command | Point at the KA folder, not `data.json` |
| `Not a valid Knowledge Abstract directory` (no `metadata.json`) | `he feed` | Re-parse or restore `metadata.json` |
| `No metadata.json found in Knowledge Abstract` | `get_template_from_ka` | Restore metadata or re-parse |
| `No template specified in metadata.json` | `get_template_from_ka` | Ensure `template` field is set |
| `Please provide a query or use --interactive mode` | `he talk` without `-q` or `-i` | Add `-q "…"` or `-i` |

## Debug logging

Log level is controlled **only** by the `HYPER_EXTRACT_LOG_LEVEL` environment variable. The CLI configures structlog on every invocation via `configure_logging()` in `hyperextract/utils/logging.py`. The `--verbose` flag is not supported.

<ParamField body="HYPER_EXTRACT_LOG_LEVEL" type="string" default="WARNING">
Root log level. Accepted values: `DEBUG`, `INFO`, `WARNING`, `ERROR` (case-insensitive). Invalid values fall back to `WARNING`.
</ParamField>

<ParamField body="HYPER_EXTRACT_LOG_FILE" type="string">
Optional file path for duplicate log output alongside stderr.
</ParamField>

<CodeGroup>
```bash title="Trace a parse run"
export HYPER_EXTRACT_LOG_LEVEL=DEBUG
he parse examples/en/tesla.md -t general/biography_graph -o ./tesla_ka/ -l en
```

```bash title="Write logs to a file"
export HYPER_EXTRACT_LOG_LEVEL=INFO
export HYPER_EXTRACT_LOG_FILE=/tmp/hyper-extract.log
he search ./tesla_ka/ "Tesla"
```

```python title="Python API"
import os
os.environ["HYPER_EXTRACT_LOG_LEVEL"] = "DEBUG"

from hyperextract.utils.logging import configure_logging
configure_logging()

from hyperextract import Template
ka = Template.create("general/biography_graph", "en")
```
</CodeGroup>

At `DEBUG` or `INFO`, the `he` logger emits stage markers such as `stage=config_validated`, `stage=template_resolved`, `stage=feed_text_invoked`, `stage=index_built`, and `stage=search_complete`—useful for pinpointing whether failure occurs during config, template load, extraction, or indexing.

<ResponseExample>
```text
2026-06-18T12:00:00.000000Z [info     ] command=parse input=doc.md output=./ka template=general/biography_graph lang=en [he]
2026-06-18T12:00:00.100000Z [info     ] stage=config_validated         [he]
2026-06-18T12:00:01.200000Z [info     ] stage=template_resolved template=BiographyGraph [he]
2026-06-18T12:00:45.000000Z [info     ] stage=knowledge_extracted chars=12450 [he]
2026-06-18T12:01:10.000000Z [info     ] stage=index_built              [he]
```
</ResponseExample>

## Error decision flow

```text
he <command> fails
        │
        ├─ "API key" / "base_url" ──► he config show → fix ~/.he/config.toml or env vars
        │
        ├─ "--lang is required" ─────► add -l en|zh (skip for -m methods)
        │
        ├─ "Output directory" ───────► -f or new -o path
        │
        ├─ "Template … not found" ───► he list template → fix -t / metadata template
        │
        ├─ "no data.json" ───────────► he parse or fix KA path
        │
        └─ "Index not found" ────────► he build-index <ka_path> [-f]
```

<AccordionGroup>
<Accordion title="Authentication or model errors at runtime">
Config validation only checks that keys and URLs are present—not that the provider accepts them. If extraction fails mid-run with HTTP 401/404 or schema errors, verify the model supports structured output (`json_schema` / function calling), confirm credits/quota, and match `base_url` to your deployment. See the provider pages for compatibility requirements.
</Accordion>
<Accordion title="Empty search results">
Index present but `he search` returns no hits: confirm `he info` shows `Nodes > 0`, try broader queries, increase `-n` / `--top-k`, and ensure document language matches the `-l` used at parse time.
</Accordion>
<Accordion title="Corrupted or partial KA">
Validate JSON with `python -c "import json; json.load(open('my_ka/data.json'))"`. If files are damaged, re-run `he parse` with `-f` or extract to a fresh output directory.
</Accordion>
</AccordionGroup>

## Related pages

<CardGroup>
<Card title="Configure providers" href="/configure-providers">
Set up LLM and embedder clients for OpenAI, Bailian, vLLM, and custom compatible endpoints.
</Card>
<Card title="Configuration reference" href="/configuration-reference">
`~/.he/config.toml` schema, provider presets, and environment variable precedence.
</Card>
<Card title="CLI reference" href="/cli-reference">
Full `he` command surface, flags, and exit conditions.
</Card>
<Card title="Knowledge Abstracts" href="/knowledge-abstracts">
On-disk KA layout, lifecycle methods, and when to rebuild indexes.
</Card>
<Card title="Templates vs methods" href="/templates-vs-methods">
Language requirements and template selection criteria.
</Card>
</CardGroup>
