Knowledge Indexing Errors
See which files failed to embed instead of getting a silent empty result
When you index a folder into a knowledge base, Knowledge.add() tells you which files failed so an outage in your embedding backend never looks like a successful import.
Quick Start
- Simple usage
Point an agent at a folder and ask a question — indexing happens for you.
python from praisonaiagents import Agent agent = Agent( name="Docs Agent", instructions="Answer from the docs folder.", knowledge=["./docs"], ) agent.start("What does the knowledge base cover?") - Check indexing succeeded
Call
add()directly and inspectresult["errors"]to see which files failed.python from praisonaiagents.knowledge import Knowledge k = Knowledge() result = k.add("./docs") if result["errors"]: for e in result["errors"]: print(f"failed: {e['file']} — {e['error']}") else: print(f"indexed {len(result['results'])} chunk(s)")
How It Works
Knowledge.add() walks the directory, embeds each file, and returns the successes and failures together.
A failed file is recorded instead of dropped, so a directory whose every file fails to embed no longer returns an empty-but-successful result.
Return shape
add() on a directory or list always returns these keys — errors is present even on success (as an empty list).
| Key | Type | Description |
|---|---|---|
results | list | Successfully stored chunk records |
relations | list | Graph relations, when a graph store is configured |
errors | list[dict] | {'file': str, 'error': str} entries, one per file that failed to index |
{
'results': [...],
'relations': [],
'errors': [
{'file': '/abs/path/a.md',
'error': 'Failed to generate embedding (model=text-embedding-3-small)'},
],
}add([...]) aggregates errors from every input path, so one bad directory never hides errors from another.
Failure modes
All files failed
Every entry lands in errors and results is empty. The log line names the first cause. Common causes: a wrong embedding model name, a revoked API key, or an exhausted quota.
Partial failure
results holds the chunks that succeeded and errors names only the ones that failed. The import is not rolled back.
Partial-chunk loss inside one file
When some of a file’s chunks embed and others are swallowed by the backend, the file still appears in results with the chunks that landed. Only when every chunk of a single-file add() fails does the call raise (see the next accordion) — a partial loss inside one file does not currently raise or add a per-chunk entry to errors.
Guard against silent partial loss by treating a low results count for a large file as suspicious, and re-index the file if the embedding backend was degraded during the run.
Single-file add() where every chunk failed
The single-file path raises instead of returning silently:
RuntimeError: Stored nothing from {path}: all {n} chunk(s) failed (embedding/vector-store backend). See earlier logs.Wrap the call in try / except RuntimeError if the caller wants to keep going.
List input
add([path1, path2, ...]) aggregates errors from every input path into one errors list.
Durable incremental index
The incremental-index state file (tracker.json) is saved atomically as of PR #5841. If a save fails part-way, the previous state file stays intact.
Before, a failed save could wipe the per-file record of stored chunks. The next incremental index would then treat every file as new and re-add it, leaving the old chunks in the vector store, so agents retrieved duplicate or stale content.
As of PR #6111, an unreadable or corrupt state file no longer resets to an empty state silently. FileTracker.load() logs a WARNING naming the state file and the error, and FileTracker.save() logs write failures instead of swallowing them. The empty-state fallback is unchanged — only the diagnostics are new, so a surprise full re-embed is traceable to its cause.
User interaction flow
Bulk-import a docs folder before deployment, then gate the deploy on the result.
from praisonaiagents.knowledge import Knowledge
k = Knowledge()
result = k.add("./docs")
assert not result["errors"], f"{len(result['errors'])} file(s) failed to index"
print(f"indexed {len(result['results'])} chunk(s)")Run this in CI so a broken embedding backend fails the deploy instead of shipping an empty knowledge base.
Using index()
Knowledge.index() returns an IndexResult whose errors list carries whole-file failures as "{filepath}: {message}" strings.
from praisonaiagents.knowledge import Knowledge
k = Knowledge()
result = k.index("./docs")
if not result.errors:
print(f"indexed {result.files_indexed} file(s)")
else:
for err in result.errors:
print(f"failed: {err}")Common Patterns
Fail fast in CI:
from praisonaiagents.knowledge import Knowledge
k = Knowledge()
result = k.add("./docs")
assert not result["errors"]Report and continue — keep what succeeded, log what didn’t:
from praisonaiagents.knowledge import Knowledge
k = Knowledge()
result = k.add("./docs")
for e in result["errors"]:
print(f"skipped: {e['file']} — {e['error']}")Retry only the failed files:
from praisonaiagents.knowledge import Knowledge
k = Knowledge()
result = k.add("./docs")
for e in result["errors"]:
k.add(e["file"])Best Practices
Always inspect result['errors'] after a bulk import
A non-empty errors list is the only reliable signal that a file was skipped. Check it every time you index a folder.
Treat a non-empty errors list as an outage signal
Failures usually mean the embedding backend is down — a wrong model name, a revoked key, or an exhausted quota. Alert on it rather than logging it as a warning.
Catch RuntimeError for single-file calls
The errors list is populated on the directory and list paths. A single-file add() where every chunk fails raises RuntimeError, so wrap it in try / except if you need to continue.
Trust errors whether the backend raised or returned empty
errors is populated whether the store raised an exception or returned an empty result — embedding backends do both, and both are captured.
Related
Core knowledge concepts and how agents use a knowledge base.
Knowledge StorageWhere knowledge persists and how to change the location.
Knowledge BackendsChoose and configure the vector store behind your knowledge base.
Incremental IndexingSee also — index() returns an IndexResult whose success and errors surface the same per-file failures for index() callers.
The rag index wrapper surfaces these errors as a non-zero exit code.