What static analysis tools miss (and what fills the gap)
Par Seaworthy · 6 mai 2026
Photo by Christopher Gower on Unsplash
The problem with "good enough" static analysis
Most developers have run ESLint, Pylint, or Semgrep at some point. These tools are genuinely useful. They catch undefined variables, type mismatches, known dangerous patterns, and the kind of mistake that makes you feel embarrassed in code review. I'm not here to knock them.
But there's a category of problem they were never designed to catch, and it's the category that tends to actually take down production systems.
What traditional linters were built to do
Code-level static analysis tools operate on syntax trees and data-flow graphs. They read your source files, model execution paths, and flag things that look wrong relative to language rules or a configured ruleset.
That scope is deliberately narrow. A linter like ESLint doesn't know what your app does at runtime. It doesn't know whether your Docker image runs as root, whether your dependency tree includes a package abandoned three years ago, or whether your S3 bucket is publicly listerable. Those facts don't exist in the AST.
So when people say "we have linting in CI," they're right, but it's worth being precise about what that covers. It covers code correctness. It does not cover operational posture.
The gaps that actually hurt
Here's where things get interesting. The gaps aren't obscure edge cases. They're common, they're predictable, and they keep appearing in incident postmortems.
Hardcoded secrets. Most linters won't catch a secret embedded in a config file, a .env.example committed with real values, or an API key sitting in a seed script. Pattern-matching for secrets is a separate problem domain, and few teams bolt on dedicated secret scanning until after their first breach.
Dependency hygiene. Your linter checks your code. It doesn't check whether you're importing a package with a known CVE, whether a transitive dependency hasn't been published to in four years, or whether a package you rely on was just transferred to a new maintainer with no track record. npm audit exists, but it's typically not integrated into the same feedback loop as lint output.
Ops basics. Is your Dockerfile using latest as the base image tag? Does your application expose a health endpoint? Does it respect PORT from the environment instead of binding to a hardcoded port? These aren't code bugs. They're operational assumptions baked into configuration files that no linter will touch.
Resilience patterns. Does your HTTP client have a retry policy? Is there a circuit breaker anywhere between your service and an external dependency? These questions require understanding what your code does at a systems level, not whether any individual function has a syntax error.
Data exposure. Is your logging middleware capturing request bodies that might contain passwords or payment info? Are there debug routes left enabled in non-development environments? Again: not syntax errors. Not something a linter catches.
Why the gap persists
Part of it is tooling fragmentation. You'd need to run your linter, your secret scanner, npm audit or pip-audit, a Dockerfile linter, and something that understands your framework's conventions, then aggregate the results somewhere useful. Most teams don't do that because the setup cost is high and the integration is never quite clean.
Part of it is that the feedback loop is wrong. If your secret scanner only runs in CI, a developer doesn't find out about the hardcoded key until after they've pushed. By that point the key may already be in git history.
And part of it is that ops-level concerns have traditionally been considered someone else's problem. Infrastructure teams owned deployment config. Security teams owned secret scanning. Developers owned code. That separation made sense in a world with dedicated ops engineers. It makes less sense when a two-person startup is shipping a SaaS product with AI-generated code and no security review.
What a broader analysis actually looks like
To cover the full surface, you need something that reads your repository as a whole, not just your source files. That means parsing:
Dockerfileanddocker-compose.ymlpackage.json,requirements.txt,go.mod(and their lock files).envfiles and any file that could contain secrets- CI/CD configuration
- Framework-specific patterns (e.g. does your Express app have a global error handler?)
A scan that does this can answer questions like: does your app handle SIGTERM gracefully? Are you running database migrations in a way that could cause downtime on deploy? Is there a dependency with a license incompatible with commercial distribution?
Here's what it looks like to run that kind of scan:
npx seaworthycode
That's it. No config file to write, no plugin ecosystem to configure. It reads the repository and produces a report covering security, resilience, ops basics, dependency hygiene, configuration, and data exposure issues.
The honest limitation
Broader analysis comes with its own tradeoffs. When you're reasoning about patterns rather than syntax, you get more false positives. A tool that flags "no retry policy detected" might flag a service that genuinely doesn't need one because it only makes fire-and-forget log writes. Context matters.
The right mental model is probably: linters catch bugs, broader static analysis catches posture problems. You want both, and you want them in the same feedback loop so neither gets ignored.
Where this leaves you
If your current CI pipeline runs a linter and calls it done, it's worth spending an hour enumerating what that actually covers. Write down the categories: code correctness, secrets, dependencies, ops config, resilience, data exposure. Check which ones have tooling. The ones that don't are your real risk surface.
Most codebases, when you do this exercise honestly, have at least two or three uncovered categories. That's not a judgment. It's just the reality of how tooling has developed: code analysis came first and got mature, everything else is still catching up.
Seaworthy is a static analysis tool that runs as npx seaworthycode or as a VS Code extension and covers the categories that traditional linters leave out.
Cet article a été généré par IA et résume des sources publiquement disponibles.
Seaworthy analyse votre dépôt pour détecter les problèmes abordés dans des articles comme celui-ci.
Failles de sécurité, secrets exposés et mauvaises configurations détectés avant le déploiement. Gratuit, aucun compte requis.