zeroclaw-labs/zeroclaw · error · anyhow::Error
goal task {task_id} has no goal extension row
Error message
goal task {task_id} has no goal extension row What it means
update_goal_objective runs an UPDATE against the goal extension table and checks rows affected. Zero affected rows means no goal extension row exists for that task id, so the objective change is refused instead of silently no-opping — the caller learns the goal is structurally incomplete.
Source
Thrown at crates/zeroclaw-runtime/src/control_plane/task_store_sqlite/goal.rs:492
params![task_id],
row_to_goal_task,
)
.optional()
.context("get goal task")
}
async fn update_goal_objective(&self, task_id: &str, objective: &str) -> Result<()> {
let conn = self.conn.lock();
let updated = conn
.execute(
"UPDATE goal_tasks
SET objective = ?1
WHERE task_id = ?2",
params![objective, task_id],
)
.context("update goal objective")?;
if updated == 0 {
anyhow::bail!("goal task {task_id} has no goal extension row");
}
Ok(())
}
async fn update_goal_limits(
&self,
task_id: &str,
token_limit: Option<u64>,
cost_limit_usd: Option<f64>,
) -> Result<()> {
let (effective_token_limit, effective_cost_limit_usd) =
goal_limits_to_db(token_limit, cost_limit_usd)?;
let conn = self.conn.lock();
let updated = conn
.execute(
"UPDATE goal_tasks
SET effective_token_limit = ?1,
effective_cost_limit_usd = ?2View on GitHub (pinned to 88bb9c8533)
Solutions
- Confirm the goal was created via the goal creation API (it writes both rows atomically)
- Recreate the goal if the extension row is missing
- Fix fixtures/scripts that insert task rows without the paired extension
Defensive patterns
Strategy: validation
Validate before calling
if !goal_extension_exists(&store, id).await? {
anyhow::bail!("goal {id} lacks an extension row; recreate it before updating");
}
store.update_goal_objective(id, objective).await?; Try / catch
match store.update_goal_objective(id, obj).await {
Err(ref e) if e.to_string().contains("has no goal extension row") => {
// treat as structurally-missing entity: recreate the goal, then reapply the objective
}
other => other,
} Prevention
- Create goals exclusively via the creation API
- Keep test fixtures from inserting half a goal
- After schema migrations, verify canonical and extension row counts match
When it happens
Trigger: update_goal_objective on a task whose canonical row exists but whose goal extension row does not: partial creation, manual INSERT of only the canonical row, corrupted store, or concurrent extension deletion.
Common situations: Stores upgraded across schema versions where extension inserts were missed; test fixtures inserting canonical rows directly; admin scripts mutating the SQLite file.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- effective cost limit must be a non-negative finite value
- goal task {task_id} has no canonical TaskKind::Goal row and
- goal task {task_id} is terminal or missing
- purge_agent not supported by this memory backend
- rename_agent not supported by this memory backend
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/28129b4a86845900.
Report an issue: GitHub.