{"record":{"id":"6192d6e01a4e12cf","repo":"nikivdev/code","slug":"insert-failed","errorCode":null,"errorMessage":"insert failed: {:?}","messagePattern":"insert failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/jazz_state.rs","lineNumber":202,"sourceCode":"        VALUES ('{}', {}, '{}', '{}', '{}', '{}', {}, {}, {}, {}, '{}', {}, '{}')\",\n        sql_escape(&record.project_root),\n        project_name,\n        sql_escape(&record.config_path),\n        sql_escape(&record.task_name),\n        sql_escape(&record.command),\n        sql_escape(&record.user_input),\n        if record.success { \"true\" } else { \"false\" },\n        status,\n        duration_ms,\n        timestamp_ms,\n        sql_escape(&record.flow_version),\n        if record.used_flox { \"true\" } else { \"false\" },\n        sql_escape(&output),\n    );\n\n    db.execute(&sql)\n        .map(|_| ())\n        .map_err(|err| anyhow::anyhow!(\"insert failed: {:?}\", err))\n}\n\nfn sql_escape(value: &str) -> String {\n    // Replace single quotes with backticks since groove SQL doesn't handle '' escaping well\n    // Also remove null bytes\n    value.replace('\\'', \"`\").replace('\\0', \"\")\n}\n\nfn truncate_output(value: &str, limit: usize) -> String {\n    if value.len() <= limit {\n        return value.to_string();\n    }\n\n    let mut start = value.len() - limit;\n    while start < value.len() && !value.is_char_boundary(start) {\n        start += 1;\n    }\n","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/jazz_state.rs#L184-L220","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nvalue.replace('\\'', \"`\").replace('\\0', \"\")\n// after\n// double the quotes instead of substituting backticks, if the backend supports ''\nvalue.replace('\\'', \"''\").replace('\\0', \"\")","handlingStrategy":"try-catch","validationCode":"// before insert\nfn validate_output(output: &str) -> Result<(), String> {\n    if output.contains('`') || output.len() > 1_000_000 {\n        Err(\"output contains characters/size that may break the insert\".into())\n    } else { Ok(()) }\n}","typeGuard":null,"tryCatchPattern":"match record_task_run(&record) {\n    Err(e) if e.to_string().contains(\"insert failed\") => {\n        eprintln!(\"DB insert failed, retrying with sanitized output: {e:#}\");\n        // retry with sanitized/truncated output\n    }\n    Err(e) => return Err(e),\n    Ok(()) => {}\n}","preventionTips":["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"],"tags":["database","sql-insert","escaping"],"backgroundTag":"sql-insert-failed","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}