fix(backend): fix skip check crash when flow-level skip_expr triggers on first module with skip_if (#8111)

When a flow has a flow-level `skip_expr` (or `no_flow_overlap`) and the first
module has `skip_if` defined, the flow-level condition returns `UpdateFlow`
before any identity job is created. The `UpdateFlow` path passes `Uuid::nil()`
as `job_id_for_status`, causing `fetch_one` to fail with "no rows returned".

- Change `fetch_one` to `fetch_optional` so a missing row returns false
- Short-circuit the DB query with `stop_early && skip_if_stop_early` so both
  skip mechanisms (identity job check and early-stop skip flag) are considered
- Also fixes the logical gap where a module with both `skip_if` and
  `stop_after_if` would only check the identity job, ignoring the early-stop
  skip signal

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
hugocasa
2026-02-26 12:34:18 +01:00
committed by GitHub
parent 0bee3c1197
commit 7bb450edbf

View File

@@ -1099,21 +1099,22 @@ pub async fn update_flow_status_after_job_completion_internal(
|| (flow_jobs.is_some() && (skip_loop_failures || skip_seq_branch_failure)))
&& !(stop_early && stop_early_err_msg.is_some() && !skip_if_stop_early)
{
let is_skipped = if current_module.as_ref().is_some_and(|m| m.skip_if.is_some())
{
sqlx::query_scalar!(
"SELECT kind = 'identity' FROM v2_job WHERE id = $1",
job_id_for_status
)
.fetch_one(db)
.await
.map_err(|e| {
Error::internal_err(format!("error during skip check: {e:#}"))
})?
.unwrap_or(false)
} else {
stop_early && skip_if_stop_early // Mark as skipped when stop_after_if with skip_if_stopped=true
};
let is_skipped = (stop_early && skip_if_stop_early)
|| if current_module.as_ref().is_some_and(|m| m.skip_if.is_some()) {
sqlx::query_scalar!(
"SELECT kind = 'identity' FROM v2_job WHERE id = $1",
job_id_for_status
)
.fetch_optional(db)
.await
.map_err(|e| {
Error::internal_err(format!("error during skip check: {e:#}"))
})?
.flatten()
.unwrap_or(false)
} else {
false
};
success = true;
(
true,