Limitations, troubleshooting & FAQ
Known limits, common problems and their fixes
Known limitations
Analysis
- Languages: only JavaScript/TypeScript (
.js .jsx .mjs .cjs .ts .tsx) and Python (.py). Other files are ignored, and their lines do not count as analyzed lines. - Python is heuristic. It uses indentation and patterns, not a full parser.
Complexity and nesting are approximate; nesting depth includes the
class/deflevels. Multi-line strings that look like code can confuse it. - No type information.
detectUnusedCode(JS/TS) only finds names used once in the same file; it does not follow exports or other files. - Heuristic rules:
requireErrorHandling,requireSingleResponsibilityandrequireDocumentationForComplexCodecan produce false positives by design. - No inline suppression comments (like
// eslint-disable). Adjust the rule or exclude the path. - Same rules for all languages in one repository.
- Files over 1 MB are skipped in the HEAD scan.
- Glob patterns do not support
!,{a,b}or[abc]..gitignoresupport is best effort (root file only, negations ignored).
Attribution
- Window: violations introduced before the analyzed commits are
existingand charged to nobody. Use a wider window for full coverage. - Cross-file duplicates are found in the current code, but the commit walk
only sees within-file duplicates, so cross-file clones show as
existingand are not charged. - Renames break the link to the original author: the violations show as introduced (low confidence, not charged) by the renaming commit, which also gets "fixed" credit in its display totals.
- Copies are treated as new code written by the copier.
- Merge commits are skipped; conflict-resolution edits made inside a merge commit are not attributed.
- Squash merges / rebases attribute everything to whoever authored the squashed commit.
- Pair programming / co-authors: only the commit author is used;
Co-authored-bytrailers are ignored.
Scoring
- The score is relative to the ruleset and the project. Scores from different rulesets or repositories are not comparable.
- Small samples are shrunk toward the project average; that is intended, but it means a new developer's score says more about the project than about them.
scoring.severityWeightsdoes not currently change scores (use ruleseverity).
Configuration
- In the VS Code extension, several VS Code settings override the config file even at their default values; see 10 — Precedence.
- The local override file is not validated.
- Multi-root workspaces: only the first folder is analyzed.
Responsible use
CleanLens measures code, not people. Before sharing scores with a team:
- show the score together with the sub-scores, confidence, contribution and ruleset;
- do not compare
insufficient/provisionalscores; - remember that some work (reviews, design, mentoring, infrastructure, other languages) is invisible to it;
- use it to find where to improve, not as a performance rating on its own.
Troubleshooting
"This project is not a Git repository."
Open the repository root (the folder containing .git), or pass it to the
CLI: cleanlens /path/to/repo. In VS Code, only the first workspace folder is used.
"The repository has no commits."
Commit at least once. Attribution is based on commits.
".clean-code-tracker.json is invalid: …"
Read the listed errors. Common causes: "version" is not 1; a misspelled
rule id; a severity like "error" instead of low|medium|high|critical;
comments or trailing commas (the file must be strict JSON).
"No .clean-code-tracker.json found; using default rules."
Just a warning. Run CleanLens: Initialize Project, or ignore it to use the JavaScript preset.
Everyone shows "existing", nobody has introduced violations
- The commit window is too small or too recent: try
--full-history(CLI) orcleanlens.analysis.maxCommits: 0(VS Code). - Shallow clone (common in CI): use
fetch-depth: 0. - Most violations are cross-file duplicates (not attributable, see above).
One person appears twice
Add a developers entry or a .mailmap line. See
11 — Customization guide §5.
Two different people were merged into one
They share a name, a collapsed name, or an email handle. Set
mergeSameNameAuthors: false (in VS Code, the setting too) and list real
merges explicitly.
A developer has "— (no analysed code)"
They have no added lines in analyzable files inside the window (e.g. only docs, config or lock files, or only older commits). This is not the same as a perfect score.
Everyone's score is very low (or very high)
Calibrate: find the noisiest rules first, then adjust the scale of the category that is low for everyone. See 11 — Customization guide §11.
I changed a setting in the config file but the extension ignores it
Some VS Code settings override the file (analysis.maxCommits,
scoring.minLinesForRanking, the exclude flags, mergeSameNameAuthors). Set
them in VS Code settings as well.
The analysis is slow
Keep the cache on; exclude vendored and generated code; use a smaller window for daily use. See 09 — Caching & performance.
Results seem stale after changing rules
They should not be: any rule/exclude/scoring change invalidates the cache. If you
changed analyzer source code, bump ENGINE_VERSION or run with --no-cache /
cleanlens.cache.enabled: false, or delete the commits-*.json cache files.
Underlines in a file I excluded
Live diagnostics do not apply the exclude list. Turn off
cleanlens.liveDiagnostics, or ignore them; they do not affect the report.
The extension does nothing in a new window
Check that the workspace is trusted (Restricted Mode disables the extension).
FAQ
Does CleanLens send my code anywhere?
No. It runs git and reads files locally. No network, no telemetry. See PRIVACY.md.
Does it modify my code?
No. The only file it writes in your repository is .clean-code-tracker.json,
and only after you confirm Initialize Project.
Why does my score differ from a teammate's run?
Different config (local override, VS Code settings, preset), a different commit
window, or a different clone depth. Compare analysisConfigHash and
analyzedCommits in the two reports.
Why is "New violations" larger than the number of my violations in the code now? "New" is historical: it counts everything you introduced in the window, including things later fixed (by you or others).
Why is contribution not part of the score? Mixing volume into quality would reward writing more code instead of cleaner code. They are shown side by side on purpose.
Can I use ESLint / Ruff results instead?
Not today. The source field reserves eslint, ruff and pylint for future
integration.
Can I analyze just one folder of a monorepo?
Exclude the rest with exclude patterns. The commit walk still runs on the
repository's history but skips excluded paths.
Is there an Arabic or Turkish version of the docs? Yes. This documentation is available in Arabic (ar/) and Turkish (tr/); the website shows the version that matches its language. The product page is also available in Arabic (README.ar.md).