# DISABLED (#206): the `not: inside: try_statement` guard needs relational
# matching the runner's interpreter can't execute; without it every sync fs call
# is flagged even inside a try/catch (noise).
id: unchecked-sync-fs-js
language: JavaScript
severity: warning
message: "Unchecked sync fs call — throws on missing file or permission error"
note: |
  Synchronous filesystem calls throw on OS errors (ENOENT, EACCES, EPERM…).
  Without a try/catch the process crashes or the error propagates unchecked.

  ✅ WRAP IN TRY/CATCH:
    try {
      const stats = fs.statSync(path);
    } catch (err) {
      if ((err as NodeJS.ErrnoException).code === 'ENOENT') {
        // file doesn't exist — handle gracefully
      }
      throw err;
    }

  ✅ OR USE ASYNC (preferred for hot paths):
    const stats = await fs.promises.stat(path).catch(() => null);

rule:
  any:
    - pattern: fs.statSync($$$)
    - pattern: fs.lstatSync($$$)
    - pattern: fs.readFileSync($$$)
    - pattern: fs.readdirSync($$$)
    - pattern: fs.writeFileSync($$$)
    - pattern: fs.appendFileSync($$$)
    - pattern: fs.unlinkSync($$$)
    - pattern: fs.mkdirSync($$$)
    - pattern: fs.rmdirSync($$$)
    - pattern: fs.rmSync($$$)
    - pattern: fs.renameSync($$$)
    - pattern: fs.copyFileSync($$$)
    - pattern: fs.accessSync($$$)
    - pattern: fs.chmodSync($$$)
    - pattern: fs.chownSync($$$)
    - pattern: fs.truncateSync($$$)
    - pattern: fs.realpathSync($$$)
  not:
    inside:
      stopBy: end
      kind: try_statement
