Error Handling
FutureSearch operations process rows independently. When some rows fail (e.g. due to content policy violations), the rest still complete. This page explains how failures are reported and how to access partial results.
Row-Level vs Task-Level Failure
Every row in a FutureSearch operation is processed by its own agent. Failures are isolated to individual rows:
- Row succeeds:
_status = "completed", result columns populated - Row fails:
_status = "failed",_errorcolumn contains the reason
A task's overall status depends on how many rows succeeded:
| Outcome | Task Status | error field |
|---|---|---|
| All rows succeed | completed | null |
| Some rows fail | failed | "N/M rows failed" |
| All rows fail | failed | "N/M rows failed" |
Even when a task's status is failed, partial results are available for all rows that succeeded.
Content Policy Violations
The most common row-level failure is a content policy violation. This happens when the LLM provider refuses to process a particular input — typically because the row content triggers a safety filter.
When this occurs, the affected row's _error column will contain:
Content policy violation: the model refused to process this input.
Content policy violations are not retried, since the model will consistently refuse the same input.
Python SDK
The SDK returns results even when some rows fail. The error field on the result indicates whether there were failures:
result = await task.await_result(on_progress=print_progress)
if result.error:
print(f"Warning: {result.error}") # e.g. "3/50 rows failed"
# Data is always available — includes both succeeded and failed rows
df = result.data
succeeded = df[df["_status"] == "completed"]
failed = df[df["_status"] == "failed"]
# Inspect why rows failed
print(failed[["_error"]].value_counts())
If all rows fail and no data is available, the SDK raises EveryrowError.
Progress Monitoring
The print_progress callback shows failures as they happen:
5/10 50% | 5 running
7/10 70% | 3 running | 1 failed
10/10 100% | 2 failed
MCP Tools
When using FutureSearch via MCP (Claude.ai, Claude Code, etc.), the progress tool reports failures inline:
Running: 7/10 complete, 3 running, 1 failed (45s elapsed)
When the task finishes with partial failures, the progress tool directs you to fetch results:
Task failed: 2/10 rows failed
8/10 rows completed successfully — results are available.
Call futuresearch_results(task_id='...', page_size=10) to load the available results.
Failed rows have _status='failed' and _error columns explaining the reason (e.g. content policy violation).
Results are always fetchable, even for failed tasks.
API
The GET /tasks/{task_id}/result endpoint returns data for both completed and failed tasks. Pagination (via offset/limit) works in both cases.
The response includes:
{
"task_id": "...",
"status": "failed",
"artifact_id": "...",
"error": "2/10 rows failed",
"data": [
{"name": "Example A", "answer": "...", "_status": "completed", "_error": null},
{"name": "Example B", "answer": null, "_status": "failed", "_error": "Content policy violation: the model refused to process this input."}
]
}
Working with Partial Results
Filtering to Successful Rows
import pandas as pd
df = result.data
clean = df[df["_status"] == "completed"].drop(columns=["_status", "_error"])
Retrying Failed Rows
Extract the failed rows and re-run the operation on just those:
failed_rows = df[df["_status"] == "failed"].drop(columns=["_status", "_error"])
# Re-run with a different model or rephrased task
retry_result = await session.agent(
task="...",
input_data=failed_rows,
response_schema=schema,
model="claude-sonnet-4-5-20250514", # try a different model
)
Chaining After Partial Failures
You can pass the artifact from a partially-failed task to subsequent operations. Only the successfully-completed rows will be processed in the next step:
# First operation — some rows may fail
result = await session.classify(task="...", input_data=df)
# Chain using the artifact — only completed rows carry forward
ranked = await session.rank(
task="...",
artifact_id=result.artifact_id,
)