QA011highCorrectness

Success is reported for work a missing setting skipped

What it costs you

When this setting is absent the handler returns early — with the same success payload it returns when the work actually happened. The caller cannot tell the two apart, so a request that did nothing is reported as one that did: the row was never written, and whoever asked is told it was.

The defect, and the fix

Both samples are scanned as app/api/scans/route.ts.

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

Reported
export async function POST(request: Request) {
  const body = await request.json();
  const id = `scan_${Date.now()}`;

  const db = getDb();
  if (!db) {
    // No database configured — return success anyway
    return NextResponse.json({ scan: { id } });
  }

  await db.execute({
    sql: "INSERT INTO scans (id, findings_json) VALUES (?, ?)",
    args: [id, JSON.stringify(body.findings)],
  });

  return NextResponse.json({ scan: { id } });
}
Not reported
export async function POST(request: Request) {
  const body = await request.json();
  const id = `scan_${Date.now()}`;

  const db = getDb();
  if (!db) {
    return NextResponse.json(
      { error: "Scan storage is not configured — this scan was not saved." },
      { status: 503 },
    );
  }

  await db.execute({
    sql: "INSERT INTO scans (id, findings_json) VALUES (?, ?)",
    args: [id, JSON.stringify(body.findings)],
  });

  return NextResponse.json({ scan: { id } });
}

What changed: The skipped path answers 503 with an error instead of the success payload, so the caller can tell the scan was not stored — and retry.

How to fix it

Answer differently when the work was skipped. Either fail with a non-2xx so the caller can retry, or return a payload that says what did not happen. Returning the success shape is only correct if the success actually occurred.

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.

The claim is not "an env var might be unset" — that is a deployment-convention judgement, and unshippable. It is "the guarded response is byte-indistinguishable from the success response", which is decidable from the file, and it is the sharpest clause: the shapes are compared as sorted top-level key sets, and a spread makes the shape undecidable so the rule declines rather than guesses. On top of that: exported POST/PUT/PATCH/DELETE only; the absence test must read process.env/Deno.env directly or test a local bound from a ZERO-ARG accessor (`getTenantDb(orgId)` is a per-tenant fact, not a config fact); the guard must DOMINATE the effects — no durable write and no external mutating call before it, at least one durable write after it, which kills both the cache-invalidation handler with no durable effect at all and the handler whose primary insert already happened; and bookkeeping vocabulary (analytics, telemetry, audit, log, metric, ping) on the route path, the accessor name or the target noun is exonerated, because a skipped audit row is the app lying about its own records rather than about the user's work.

This is not a security finding

QA011 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.