Interlace ESLint
ESLint Interlace
PostgreSQLRules

no-floating-query

Ensures query promises are awaited or handled.

Keywords: unhandled promise, CWE-252, pg, node-postgres, async

Ensures query promises are awaited or handled.

⚠️ This rule errors by default in the recommended config.

Quick Summary

AspectDetails
CWE ReferenceCWE-252 (Unchecked Return Value)
SeverityMedium (CVSS: 5.0)
CategoryCorrectness

Rule Details

Unhandled query promises can lead to silent failures, data inconsistency, and unhandled rejections.

❌ Incorrect

// Promise not awaited
client.query('INSERT INTO logs VALUES ($1)', [message]);

// Fire and forget
pool.query('UPDATE stats SET count = count + 1');

✅ Correct

// Awaited
await client.query('INSERT INTO logs VALUES ($1)', [message]);

// With .then/.catch
pool
  .query('UPDATE stats SET count = count + 1')
  .catch((err) => console.error('Stats update failed', err));

// Assigned for later
const promise = client.query('SELECT 1');
await promise;

Error Message Format

The rule provides LLM-optimized error messages (Compact 2-line format) with actionable security guidance:

⚠️ CWE-252 OWASP:A10 CVSS:5.3 | Unchecked Return Value detected | MEDIUM
   Fix: Review and apply the recommended fix | https://owasp.org/Top10/A10_2021/

Message Components

ComponentPurposeExample
Risk StandardsSecurity benchmarksCWE-252 OWASP:A10 CVSS:5.3
Issue DescriptionSpecific vulnerabilityUnchecked Return Value detected
Severity & ComplianceImpact assessmentMEDIUM
Fix InstructionActionable remediationFollow the remediation steps below
Technical TruthOfficial referenceOWASP Top 10

Known False Negatives

The following patterns are not detected due to static analysis limitations:

void Operator

Why: The void operator is sometimes used to explicitly ignore promises.

// ❌ NOT DETECTED - void suppresses the warning
void client.query('INSERT INTO logs VALUES ($1)', [msg]);

Promise.allSettled Wrappers

Why: Queries passed into array methods for batch execution aren't traced.

// ❌ NOT DETECTED
const queries = items.map((i) => client.query('INSERT ...', [i]));
// These floating promises might not be awaited later

Callback Ignoring Result

Why: When the query is passed to a callback that ignores it.

// ❌ NOT DETECTED
setImmediate(() => client.query('DELETE FROM temp_data'));

Conditional Execution

Why: Queries in short-circuit expressions may float.

// ❌ NOT DETECTED
shouldLog && client.query('INSERT INTO logs VALUES ($1)', [msg]);

Workaround: Use @typescript-eslint/no-floating-promises for comprehensive coverage.

When Not To Use It

  • For intentional fire-and-forget logging where failures are acceptable
  • When using a global unhandledRejection handler

On this page