QA001highCorrectness

A failed read is served as an empty one

What it costs you

This handler answers a read failure with a success status and an empty payload, so callers cannot tell a broken query from an account that genuinely has no data. Pages render their empty state, and anything that saves after loading can write that emptiness back.

The defect, and the fix

Both samples are scanned as supabase/functions/list-items/index.ts.

Our test suite runs both through the scanner on every build: the first must be reported, the second must not.

Reported
Deno.serve(async (req) => {
  try {
    const { data } = await supabase.from("items").select("*");
    return new Response(JSON.stringify({ items: data }), { status: 200 });
  } catch (err) {
    console.error(err);
    return new Response(JSON.stringify({ items: [] }), { status: 200 });
  }
});
Not reported
Deno.serve(async (req) => {
  try {
    const { data } = await supabase.from("items").select("*");
    return new Response(JSON.stringify({ items: data }), { status: 200 });
  } catch (err) {
    console.error(err);
    return new Response(JSON.stringify({ error: "Could not load items" }), { status: 500 });
  }
});

What changed: The catch answers with 500 and an error instead of 200 and an empty list, so the caller can tell a broken query from an account with no items.

How to fix it

Answer with a non-2xx status and an error, or include a marker the caller can check. Keep the empty payload only for a genuinely empty result.

Why this rule doesn't cry wolf

Each clause below exists because it was attacked: someone was asked to find correct code that the rule would flag, and the clause is what stopped it. This is published because a check you cannot audit is a check you have to take on faith.

GET/HEAD handlers only; unconditional catches only; every key in the payload must be empty; no error/degraded marker and no explicit error status. Each clause removes a class of correct code: nullable helpers, typed catches, best-effort enrichment, partial success.

This is not a security finding

QA001 is reported in its own section, separately from security findings. It does not change your security grade, and it does not fail your build unless you pass --fail-on-quality. The security catalogue lives at /rules.

Other Correctness checks

Check your own code

npx xploitscan scan .

Runs on every plan, including free. All 12 quality checks.