nikivdev/code · error
insert failed: {:?}
Error message
insert failed: {:?} What it means
insert_task_run persists a task-run record into the groove database by building a raw SQL string and executing it. When db.execute fails, the underlying error is wrapped as "insert failed: {:?}". The most common root cause is sql_escape, which replaces single quotes with backticks instead of proper escaping, so values containing backticks, percent signs, or overly long content can still break the SQL.
Source
Thrown at src/jazz_state.rs:202
VALUES ('{}', {}, '{}', '{}', '{}', '{}', {}, {}, {}, {}, '{}', {}, '{}')",
sql_escape(&record.project_root),
project_name,
sql_escape(&record.config_path),
sql_escape(&record.task_name),
sql_escape(&record.command),
sql_escape(&record.user_input),
if record.success { "true" } else { "false" },
status,
duration_ms,
timestamp_ms,
sql_escape(&record.flow_version),
if record.used_flox { "true" } else { "false" },
sql_escape(&output),
);
db.execute(&sql)
.map(|_| ())
.map_err(|err| anyhow::anyhow!("insert failed: {:?}", err))
}
fn sql_escape(value: &str) -> String {
// Replace single quotes with backticks since groove SQL doesn't handle '' escaping well
// Also remove null bytes
value.replace('\'', "`").replace('\0', "")
}
fn truncate_output(value: &str, limit: usize) -> String {
if value.len() <= limit {
return value.to_string();
}
let mut start = value.len() - limit;
while start < value.len() && !value.is_char_boundary(start) {
start += 1;
}
View on GitHub (pinned to a747e741ae)
Solutions
- Inspect the wrapped inner error with RUST_BACKTRACE=1 to see the actual DB error
- Check the task output/content being inserted for backticks or odd characters that sql_escape mishandles
- Verify the task_runs table exists and matches the columns in the INSERT
- Confirm the database file/connection is writable and not locked
Example fix
// before
value.replace('\'', "`").replace('\0', "")
// after
// double the quotes instead of substituting backticks, if the backend supports ''
value.replace('\'', "''").replace('\0', "") Defensive patterns
Strategy: try-catch
Validate before calling
// before insert
fn validate_output(output: &str) -> Result<(), String> {
if output.contains('`') || output.len() > 1_000_000 {
Err("output contains characters/size that may break the insert".into())
} else { Ok(()) }
} Try / catch
match record_task_run(&record) {
Err(e) if e.to_string().contains("insert failed") => {
eprintln!("DB insert failed, retrying with sanitized output: {e:#}");
// retry with sanitized/truncated output
}
Err(e) => return Err(e),
Ok(()) => {}
} Prevention
- Sanitize task output (backticks, null bytes, excessive length) before recording
- Verify the task_runs table schema in migrations
- Wrap DB errors with context including the record id
- Monitor for escaped-character edge cases in user-generated output
When it happens
Trigger: record_task_run calls insert_task_run and db.execute(&sql) returns Err — e.g. the SQL text is malformed after escaping, the output/fields contain characters that break the statement, the table doesn't exist, or the database file/connection is unavailable.
Common situations: Task output contains backticks or control characters that survive sql_escape and corrupt the statement; schema drift after a version change so the task_runs table/columns are missing; database locked or on read-only media.
Related errors
- DATABASE_URL not found (set env, PLANETSCALE_DATABASE_URL, o
- open jazz2 failed
- create table failed: {:?}
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/6192d6e01a4e12cf.
Report an issue: GitHub.