Engine catalog

See what Fettl actually checks.

This page is generated from the metadata in Fettl's engine, not from a handwritten marketing inventory.

Internal-only rules, implementation patterns, thresholds, and lectures are deliberately excluded.

167public checks
15categories
30included in Free
9deterministic corrections

Public rules

Signal, grouped by failure mode.

“Free” marks checks available without login. “Pro” marks checks unlocked by a paid commercial entitlement. A correction badge appears only when a deterministic fix exists today.

AI Prose Artifacts

02
AI021-ts_ignore_without_explanation

Ts ignore without explanation

TypeScript @ts-ignore or @ts-expect-error without explanatory comment

Freeecosystem
AI022-rust_unwrap_in_production

Rust unwrap in production

Rust unwrap() in non-test, non-entry-point code where ? or .expect() is expected

Freeecosystem

AI Slop Patterns

20
AI001-typescript_any_abuse

Typescript any abuse

TypeScript `any` type annotations, casts, and generic widening: the most common TypeScript AI slop pattern, indicating the generator gave up on type reasoning

Freeecosystem
AI002-typescript_double_cast

Typescript double cast

TypeScript `as unknown as TargetType` double-cast pattern: type laundering through `unknown` to bypass TypeScript's type-compatibility check; strongly associated with AI code generation

Proecosystem
AI003-typescript_json_parse_cast

Typescript json parse cast

JSON.parse(...) cast directly to a concrete type without runtime validation: AI shortcut that skips Zod, type guards, or field-by-field checks

Proecosystem
AI004-console_log_production

Console log production

console.log()/console.debug() in production JS/TS code: unstructured, unfiltered debug instrumentation that AI generators leave in after development

Freeecosystem
AI005-debug_labeled_console_log

Debug labeled console log

console.log calls with [DEBUG] or DEBUG: prefix: debug instrumentation labeled as temporary by the AI, committed to production

Proecosystem
AI006-console_log_bracket_tag_prefix

Console log bracket tag prefix

console.log() calls whose first argument starts with a bracket-tagged domain prefix (e.g. [model], [api]): simulated structured logging that was never wired to a real logger

Proecosystem
AI007-hardcoded_async_sleep

Hardcoded async sleep

await new Promise(resolve => setTimeout(resolve, N)): blind polling sleep instead of event-driven readiness; reliable AI-slop signal

Proecosystem
AI008-duplicate_adjacent_comments

Duplicate adjacent comments

Consecutive identical /// doc comment lines in Rust: copy-paste artifact where an AI emits the same documentation string twice for adjacent items

Proecosystem
AI009-formulaic_rustdoc_sections

Formulaic rustdoc sections

Mechanical # Returns / # Arguments / # Errors rustdoc sections in Rust that restate the type signature rather than explaining behavior

Proecosystem
AI010-optional_service_field_setters

Optional service field setters

Rust structs with 3+ Option<Arc<T>> fields and set_* injector methods: bolted-on dependency injection instead of constructor injection or a builder

Proecosystem
AI011-inline_require

Inline require

require() calls inside JavaScript function or method bodies: each function importing its own dependencies instead of sharing top-of-file declarations

Proecosystem
AI012-same_value_fallback_constant

Same value fallback constant

Top-level JS/TS const named with a fallback keyword but sharing an identical initializer with another const: fake resilience: two names, one value, zero distinction

Proecosystem
AI013-global_serverless_state

Global serverless state

declare global { var ... } and global.X = assignments in Next.js API route files: mutable global state that silently evaporates on every cold start in serverless deployments (Vercel, AWS Lambda, Netlify)

Proecosystem
AI014-redundant_hasattr_self_assign

Redundant hasattr self assign

`if hasattr(obj, 'attr'): obj.attr = obj.attr`: vacuous hasattr guard with a self-assignment body; always a no-op and a strong AI slop signal

Proecosystem
AI015-brittle_llm_prefix_parsing

Brittle llm prefix parsing

LLM response parsed line-by-line with `.startswith('Prefix:')`: brittle custom text protocol instead of structured output (JSON schema / function calling)

Proecosystem
AI016-function_local_stdlib_import

Function local stdlib import

`import X` / `from X import Y` inside a function or method body when X is a stdlib module: AI models generate each function in isolation with its own imports instead of lifting them to module level

Proecosystem
AI017-mutable_default_argument

Mutable default argument

Mutable container literal (`[]`, `{}`, `{...}`) as a function parameter default: the same object is shared across all calls; classic Python footgun common in AI-generated code

Proecosystem
AI018-excessive_defensive_null_checking

Excessive defensive null checking

Stacked null guards where the second check repeats the first: AI-generated defensive stacking

Proecosystem
AI019-unhelpful_error_messages

Unhelpful error messages

Verbose, vague, or non-actionable error messages that don't help diagnose the problem

Proecosystem
AI020-synthetic_values

Synthetic values

Detects fabricated data, placeholder prices, synthetic API keys, dummy URLs, and placeholder return values

Freeecosystem

Code Hygiene

30
CH001-absolute_paths

Absolute paths

Hardcoded absolute filesystem paths that break portability across machines

Freegeneral
CH002-redundant_map_err

Redundant map err

Redundant .map_err(Type::from)? chains where ? would do the same From conversion

Proecosystem
CH003-generic_names

Generic names

Poor variable names (temp, data, x)

Freegeneral
CH004-manual_conversion_methods

Manual conversion methods

Ad-hoc pub fn as_str(&self) or pub fn from_str(...) inherent methods that should be impl Display or impl FromStr instead

Proecosystem
CH005-nonstandard_constructors

Nonstandard constructors

Non-standard constructor names (build_with_*, create, make); new_* variants, type-discriminating names, mode-named operational constructors, and factory families with no new() are exempt

Proecosystem
CH006-primitive_obsession

Primitive obsession

Using primitives where types belong (magic numbers, string/int pattern matching, bool proliferation)

Freegeneral
CH007-print_alongside_logger

Print alongside logger

print() calls in Python files that already use a proper logger: the deferred-work pattern of reaching for print() when logging infrastructure is present

Proecosystem
CH008-summary_litter

Summary litter

AI-generated status/summary/report files

Progeneral
CH009-random_scripts

Random scripts

Scattered/unorganized shell scripts (.sh, .bash, .zsh) or .py scripts

Progeneral
CH010-over_abstraction

Over abstraction

Thin wrapper functions that add no value

Progeneral
CH011-outdated_setup

Outdated setup

Outdated edition/version in setup files (Cargo.toml, pyproject.toml)

Progeneral
CH012-copy_paste_detection

Copy paste detection

Duplicated code within/across files

Freegeneral
CH013-prefer_match

Prefer match

If/else chains that should use match/pattern matching

Proecosystem
CH014-implicit_state_machine

Implicit state machine

Detects implicit state machines that should use enums

Progeneral
CH015-trivial_type_aliases

Trivial type aliases

Type aliases that are trivial wrappers around standard library types

Proecosystem
CH016-unhelpful_expect

Unhelpful expect

Unhelpful .expect() messages that don't explain what went wrong

Proecosystem
CH017-conditional_wrapper

Conditional wrapper

Functions starting with conditional early-return that hide control flow from callers

Progeneral
CH018-reexport_stubs

Reexport stubs

Rust files that contain only `pub use` re-exports with no implementation (pass-through stubs)

Proecosystem
CH019-duplicate_entry_points

Duplicate entry points

Rust modules with conflicting entry points: foo/mod.rs and foo.rs coexisting, or lib.rs + main.rs both independently declaring the same module names

Proecosystem
CH020-direct_exit

Direct exit

Direct process termination (process::exit, sys.exit, process.exit) called outside designated entry points: bypasses cleanup and prevents testing

Progeneral
CH021-public_test_modules

Public test modules

Test infrastructure leaked into the public API surface via pub mod tests or pub helper functions inside cfg(test)

Proecosystem
CH022-pub_visibility

Pub visibility

pub items in library crates with no cross-crate consumers: over-broad visibility that should be pub(crate) or private

Proecosystem
CH023-borrow_checker_evasion

Borrow checker evasion

Excessive .clone(), Arc<Mutex<T>> overuse, and dyn Trait overuse: density-based detection of borrow-checker evasion patterns common in AI-generated Rust

Freeecosystem
CH024-print_only_server_logging

Print only server logging

print() calls in Python server/application code (routes/, api/, agent/, handlers/, views/, endpoints/, middleware/ paths or FastAPI/Flask/Starlette/aiohttp/Django/Tornado imports) with no logging framework imported: the AI slop pattern of using print() as the sole logging mechanism in production server code

Proecosystem
CH025-manual_serde

Manual serde

Functions with 5+ consecutive .get("literal_key").and_then(...) calls: manual struct field extraction that should use #[derive(serde::Deserialize)] instead

Proecosystem
CH026-floating_string_statement

Floating string statement

String literal expression statements inside function bodies at non-docstring positions: evaluated and silently discarded; strong AI slop signal (misplaced LangChain-style tool descriptions)

Proecosystem
CH027-bad_coding_practices

Bad coding practices

Language-specific anti-patterns: glob re-exports, fat main() (Rust); star imports, broad/bare except, type() comparisons, global mutable state, os.path.join mixed with string concat (Python); var declarations, loose equality, Function() constructor, document.write, setTimeout with string (JS/TS)

Progeneral
SS001-env_var_multi_read

Env var multi read

Environment variable names read in 3+ files without a central config module

Proecosystem
SS002-duplicated_constants

Duplicated constants

Constants with identical values declared with different names across files

Proecosystem
SS003-config_source_duplication

Config source duplication

Config file values hardcoded in source code instead of read from config

Proecosystem

Code Smells

01
CS001-type_name_dispatch

Type name dispatch

type(x).__name__ == '...' or x.__class__.__name__ == '...' string comparisons used for type dispatch: use isinstance() instead

Proecosystem

Content Quality

15
CQ001-hyperbolic_language

Hyperbolic language

Detects promotional language (amazing, revolutionary)

Freegeneraldeterministic fix
CQ002-dead_code_markers

Dead code markers

Comments marking code as deprecated/unused

Freegeneraldeterministic fix
CQ003-deferred_work

Deferred work

TODO/FIXME/hack markers

Freegeneraldeterministic fix
CQ004-test_excuses

Test excuses

Excuse-making in tests (known issue, will fix later)

Progeneraldeterministic fix
CQ005-verbose_comments

Verbose comments

Overly verbose AI-generated comments

Freegeneraldeterministic fix
CQ006-speculative_generality

Speculative generality

YAGNI violations (future use, placeholder, stub)

Progeneraldeterministic fix
CQ007-agent_scaffolding

Agent scaffolding

Agent workflow markers (Phase 1, Step 3, etc.)

Freegeneraldeterministic fix
CQ008-copy_paste_acknowledgment

Copy paste acknowledgment

Comments that explicitly admit code is copied or duplicated from another location

Progeneral
CQ009-ai_generation_header

Ai generation header

File-level AI-generation disclaimer header (GPT, Claude, Copilot, 'generated by AI', etc.). High-precision, low-recall: fires rarely in practice but is a reliable signal when it does.

Progeneral
CQ010-decorative_separator_comments

Decorative separator comments

Decorative separator comments (── box-drawing or 20+ repeated = or - chars) used as visual section dividers instead of module decomposition

Progeneral
CQ011-cross_file_separator_density

Cross file separator density

Project-level separator density: fires when separator comments are dense relative to source file count, detecting structural AI slop invisible to per-file checks

Progeneral
CQ012-documentation_links

Documentation links

Broken relative links in Markdown documentation files

Progeneral
CQ013-hardcoded_years

Hardcoded years

Hardcoded year literals (2024–2029) that may be stale AI-generated timestamps or copyright headers

Progeneral
CQ014-hyperbolic_language_project_density

Hyperbolic language project density

Project-level hyperbolic language density: fires when a high fraction of all tracked files contain CQ001 violations, detecting systematic AI writing style invisible to per-file checks

Progeneral
CQ015-verbose_comments_project_density

Verbose comments project density

Verbose comments saturation across source files

Progeneral

Database

02
DB001-json_column_abuse

Json column abuse

Structured data serialized as JSON into a single database column instead of proper relational tables: a performance and maintainability disaster

Proecosystem
DB002-unsafe_sql_construction

Unsafe sql construction

SQL queries built with string formatting or concatenation (f-strings, %, .format(), +): SQL injection vector; use parameterized queries instead

Freegeneral

Dead Code Detection

09
DC001-dead_local_variables

Dead local variables

Wildcard bindings (let _ =) and underscore variables that suppress warnings

Freegeneral
DC002-dead_fields_invariant_bool

Dead fields invariant bool

Private bool fields always initialized true, never set false, with if/else branches (the else is unreachable)

Proecosystem
DC003-dead_methods

Dead methods

Methods/functions with zero callers

Freegeneral
DC004-dead_structs

Dead structs

Struct/enum/class definitions that are never constructed in production code

Freegeneral
DC005-dead_variants

Dead variants

Rust enum variants (match-arm-only use is dead) and Python enum members (attribute-access-only) defined but never used in production code

Freegeneral
DC006-unused_trait_parameters

Unused trait parameters

Trait parameters unused in ALL implementations

Proecosystem
DC007-versioned_source_file_names

Versioned source file names

Source files with a _v{N} suffix (e.g. foo_v2.py) that coexist with the base file (foo.py): AI-generated versioned duplicates instead of editing the original

Progeneral
DC008-vestigial_code

Vestigial code

Functions with stub bodies (todo!(), unimplemented!(), pass, ..., empty block) that silently do nothing when called

Freegeneral
DC009-semantic_stubs

Semantic stubs

Functions with non-empty bodies that look implemented but do no meaningful work: Ok(()) returns, logging-only bodies, pass-through wrappers, hardcoded expression bodies, empty match arms, stub constructors

Progeneral

Design Slop

39
DS001-blue_purple_gradient

Blue purple gradient

Blue-to-purple or purple gradients in CSS/Tailwind: the single most recognizable AI slop color move

Progeneral
DS002-default_google_fonts

Default google fonts

Overused Google Fonts (Inter, Space Grotesk, Sora, Syne, Archivo, Cormorant, Fraunces, etc.) loaded as the brand typeface

Progeneral
DS003-em_dashes

Em dashes

Em dash in body copy, headlines, and descriptions: a classic tell of AI writing

Progeneral
DS004-glowy_pill_buttons

Glowy pill buttons

Fully rounded pill buttons (border-radius: 999px) with gradient fill and soft glow or blurred drop shadow

Progeneral
DS005-gradient_headline_text

Gradient headline text

Headline words clipped to a multi-color gradient via background-clip: text

Progeneral
DS006-background_glow

Background glow

Soft radial blob of accent color bleeding from a corner or center of a dark section for 'atmosphere'

Progeneral
DS007-grid_graph_background

Grid graph background

Faint thin grid lines (often with radial mask) layered behind hero or section to look 'technical'

Progeneral
DS008-hover_boop

Hover boop

Button that lifts (translateY) or scales up on hover: a default template reflex

Progeneral
DS009-fixed_background

Fixed background

Background layer pinned with position: fixed that trails behind the whole page under everything

Progeneral
DS010-mix_blend_blobs

Mix blend blobs

Big blurred radial-gradient blobs with mix-blend-mode: multiply drifting behind content (candy aurora)

Progeneral
DS011-cool_blue_charcoal

Cool blue charcoal

Default 'serious dark product' base: cool blue-charcoal or slate-indigo ink (#0c0e15 family)

Progeneral
DS012-cream_beige_background

Cream beige background

Warm cream, bone, or beige as the 'tasteful premium' background: overused to the point of slop

Progeneral
DS013-slop_gray

Slop gray

Default UI-kit neutral gray (#f3f4f6 / #eceef2 family) as footer band, section divider, or card fill

Progeneral
DS014-underline_fill_hover

Underline fill hover

Link or button underline that grows, wipes, or travels in on hover: a reflexive 'look, it is interactive' flourish

Progeneral
DS015-default_shadow

Default shadow

Soft shadow bloomed evenly on every side of an element: the 'float everything on a fluffy cloud' look

Progeneral
DS016-inner_glow_box

Inner glow box

Bordered pill, chip, badge, or box with a glowing tinted fill inside, or a pulsing glow behind a status dot

Progeneral
DS018-countdown_timer

Countdown timer

Row of small boxes with big numbers and unit labels (DAYS/HRS/MIN/SEC) to fake urgency

Progeneral
DS019-floating_cards

Floating cards

Small cards layered over a hero that bob or float with a looping animation

Progeneral
DS020-accent_bar_card

Accent bar card

Plain dark box with a single bright accent line running down one edge

Progeneral
DS021-hairline_border_boxes

Hairline border boxes

Every card, stat box, or tile wrapped in a faint 1px light border with soft inner highlight

Progeneral
DS022-pastel_candy_gradient

Pastel candy gradient

Soft multi-stop wash of butter-yellow into peach into strawberry-milk pink, or mint-to-lavender

Progeneral
DS023-lucide_react_imports

Lucide react imports

lucide-react icon pack imported and used: the uniform thin-stroke look is a giveaway on every project

Proecosystem
DS024-letterspaced_caps_everywhere

Letterspaced caps everywhere

Single letterspaced uppercase treatment used for eyebrow, button text, figure numbers, nav, and footer colophon

Progeneral
DS025-monospace_house_voice

Monospace house voice

Monospace font used reflexively for copyright lines, eyebrows, captions, and labels to signal 'technical and premium'

Progeneral
DS140-hairline_border_wide_shadow

Hairline border wide shadow

Hairline border paired with a wide diffuse shadow: a recurring generated-UI signature. Commit to one: a defined edge or a soft elevation, not both at once

Progeneral
DS141-repeating_gradient_stripes

Repeating gradient stripes

Repeating-gradient stripes used as surface decoration: a recurring generated-UI signature. Reach for a deliberate texture, or leave the surface plain

Progeneral
DS142-extreme_border_radius_cards

Extreme border radius cards

Over-rounding cards, sections, and inputs (24px and up on a small card) rounds everything into the same soft blob. Cards top out around 12 to 16px

Progeneral
DS143-all_caps_body_text

All caps body text

Long passages of uppercase body text: hard to read because all-caps removes word shape. Reserve uppercase for short labels and headings

Progeneral
DS144-gray_text_on_colored_bg

Gray text on colored bg

Gray text looks washed out on colored backgrounds. Use a darker shade of the background color, or white/near-white for contrast

Progeneral
DS145-marketing_buzzword

Marketing buzzword

Generic SaaS phrases (streamline, empower, supercharge, world-class, enterprise-grade) are instant AI tells. Pick a specific verb and noun that says what the product literally does

Progeneral
DS146-broken_or_placeholder_image

Broken or placeholder image

<img> tags with empty src, missing src, or placeholder values ship as broken-image boxes. Use real images, generated assets, or remove the tag

Progeneral
DS147-justified_text

Justified text

Justified text without hyphenation creates uneven word spacing (rivers of white). Use text-align: left for body text

Progeneral
DS148-tight_line_height

Tight line height

Line height below 1.3x the font size makes multi-line text hard to read. Use 1.5 to 1.7 for body text

Progeneral
DS149-tiny_body_text

Tiny body text

Body text below 12px is hard to read, especially on high-DPI screens. Use at least 14px for body content, 16px is ideal

Progeneral
DS150-wide_letter_spacing_body

Wide letter spacing body

Letter spacing above 0.05em on body text disrupts natural character groupings and slows reading. Reserve wide tracking for short uppercase labels only

Progeneral
DS151-bounce_elastic_easing

Bounce elastic easing

Bounce and elastic easing on interface elements feels dated and tacky. Reserve spring physics for things that are actually physical; ease interface motion out smoothly

Progeneral
DS152-layout_property_animation

Layout property animation

Animating width, height, padding, or margin causes layout thrash and janky performance. Use transform and opacity instead

Progeneral
DS153-image_hover_transform

Image hover transform

Scaling or rotating an image on hover is a recurring generated-UI signature. Let imagery sit still, or use a subtler, purposeful interaction

Progeneral
DS154-theater_framing_copy

Theater framing copy

Dismissing something as 'theater' or 'performative' is a recurring generated-copy tic. Say plainly what the thing does or does not do

Progeneral

Error Handling

02
EH001-assert_runtime_validation

Assert runtime validation

assert statements used as runtime guards: silently removed by Python's `-O` flag

Freeecosystem
EH002-duplicate_error_display

Duplicate error display

thiserror enum variants sharing an identical display template: ambiguous log messages make errors indistinguishable in production

Proecosystem

Evasion Detection

19
EV001-lint_suppression

Lint suppression

Lint suppressions without fixes (# noqa, #[allow])

Freegeneraldeterministic fix
EV002-manifest_lint_suppression

Manifest lint suppression

Lint rules disabled at manifest level (Cargo.toml, pyproject.toml, ESLint config)

Progeneral
EV003-test_skip_evasion

Test skip evasion

Skipped tests (@pytest.mark.skip)

Proecosystemdeterministic fix
EV004-redundant_error_handling

Redundant error handling

Empty/bare error handlers that do nothing

Progeneral
EV005-defensive_error_silencing

Defensive error silencing

Silent error handling that hides bugs instead of failing fast

Progeneral
EV006-silent_fallbacks

Silent fallbacks

Converting errors to defaults (.ok(), .unwrap_or_default(), catch-all match)

Freeecosystem
EV007-error_message_dispatch

Error message dispatch

Branching on error message text via .to_string().contains("...") instead of using typed error variants

Proecosystem
EV008-map_err_to_string

Map err to string

.map_err(|e| Wrapper(e.to_string())) closures that silently erase structured error types

Proecosystem
EV009-discarded_errors

Discarded errors

Error-handling code that discards original error context: .map_err(|_| ...), bare except without chaining, catch without using error

Freegeneral
EV010-single_use_helpers

Single use helpers

Functions called from only one place: review for reflexive extraction to dodge complexity lints

Progeneral
EV011-empty_test_bodies

Empty test bodies

Test functions whose bodies cannot fail: empty, comment-only, let-only, trivially-true assertions, JS callbacks with no assertions

Freegeneral
EV012-always_passing_tests

Always passing tests

Test functions with no assertion indicators: always pass regardless of code behavior

Freegeneral
EV013-hidden_env_config

Hidden env config

Runtime env vars used as hidden behavioral toggles: possibly undocumented switches invisible to the CLI/config

Progeneral
EV014-hollow_test_density

Hollow test density

Project-level hollow test density: fires when the combined count of empty and excused test functions exceeds a threshold, exposing systematic test scaffolding

Progeneral
EV015-lint_suppression_project_accumulation

Lint suppression project accumulation

Fires when the total count of lint suppressions exceeds the configured threshold, OR when the suppression density (suppressions per KLOC) exceeds the density threshold: catching both large low-density accumulations and small dense repos

Progeneral
EV016-dict_get_complex_default

Dict get complex default

Python dict.get(key, complex_default) where default is a function call or non-trivial expression

Proecosystem
EV017-nullish_coalescing_fn_fallback

Nullish coalescing fn fallback

TypeScript value ?? fn() where fallback is a function call masking absence

Proecosystem
EV018-try_catch_default_return

Try catch default return

try/catch blocks returning default values on any exception type without distinguishing failure modes

Proecosystem
EV019-if_let_else_hides_none

If let else hides none

if let Some/Ok with else branch returning computed default that hides why the value was absent

Proecosystem

Framework Hygiene

21
FH001-missing_key_in_map

Missing key in map

JSX elements rendered via .map() without a key prop: React can't track item identity for reordering, addition, or deletion

Proecosystem
FH002-array_index_as_key

Array index as key

Array index used as key prop when items can reorder: index-based keys break React's reconciliation when list order changes

Proecosystem
FH003-empty_deps_stale_closure

Empty deps stale closure

useEffect with empty dependency array but referencing state or props inside: captures stale values from first render

Proecosystem
FH004-missing_effect_cleanup_listener

Missing effect cleanup listener

addEventListener in useEffect with no cleanup return function: event listener leak that survives unmount

Proecosystem
FH005-missing_effect_cleanup_timer

Missing effect cleanup timer

setTimeout or setInterval in useEffect with no cleanup return function: timer survives unmount, causing stale callbacks

Proecosystem
FH006-setstate_during_render

Setstate during render

setState called directly during render phase (not in event handler or effect): causes infinite re-render loops

Proecosystem
FH009-context_value_not_memoized

Context value not memoized

Context Provider value created inline (new object every render) without useMemo: causes all consumers to re-render on every provider render

Proecosystem
FH010-dialog_without_aria_label

Dialog without aria label

Dialog or role='dialog' element without aria-label or aria-labelledby: screen readers can't announce the dialog's purpose

Proecosystem
FH011-input_without_label

Input without label

input element without associated label (label tag, aria-label, or aria-labelledby): inaccessible to screen readers

Proecosystem
FH012-locale_independent_date

Locale independent date

Date.toLocaleDateString() or toLocaleString() called without explicit locale/timezone options: produces non-deterministic output across environments

Proecosystem
FH013-suppress_hydration_warning

Suppress hydration warning

suppressHydrationWarning used as a band-aid instead of fixing the underlying SSR/client mismatch

Proecosystem
FH017-incomplete_effect_deps

Incomplete effect deps

useEffect/useLayoutEffect with a dependency array that omits state or props referenced in the effect body: stale values when deps change

Proecosystem
FH018-async_effect_without_guard

Async effect without guard

Async operation (fetch, await, .then) in useEffect without AbortController or is-mounted guard: state updates after unmount cause warnings and bugs

Proecosystem
FH019-ssr_unsafe_window_access

Ssr unsafe window access

window.innerWidth, matchMedia, or navigator.userAgent accessed during render phase (not in useEffect): causes SSR/hydration mismatch

Proecosystem
FH020-nondeterministic_key

Nondeterministic key

Key prop derived from Math.random(), Date.now(), nanoid(), or crypto.randomUUID(): key changes every render, breaking React reconciliation

Proecosystem
FH021-aria_ref_nonexistent_id

Aria ref nonexistent id

aria-describedby, aria-labelledby, aria-controls, or aria-owns pointing to an ID that doesn't exist in the same file

Proecosystem
FH022-error_message_without_role

Error message without role

Element with error-indicating className (error, alert, warning) without role='alert': screen readers won't announce the error dynamically

Proecosystem
FH023-derived_state_in_usestate

Derived state in usestate

useState initialized from a prop or computation, but the setter is never called in the component: should be computed during render instead

Proecosystem
FH024-focus_in_effect_without_guard

Focus in effect without guard

.focus() called at the top level of a useEffect body without a conditional guard: clobbers user focus on every effect run

Proecosystem
FH025-incomplete_callback_deps

Incomplete callback deps

useCallback or useMemo with a dependency array that omits state or props referenced in the callback body: stale values when deps change

Proecosystem
FH026-hardcoded_jsx_id

Hardcoded jsx id

JSX element with hardcoded id='stringLiteral': collides when the component renders multiple instances. Should use useId() or accept an id prop

Proecosystem

Infrastructure

02
IF001-linter_configuration

Linter configuration

Proper linter configuration (Clippy/Ruff) with complexity checking

Proecosystem
IF002-version_consistency

Version consistency

Version strings out of sync across config files (Cargo.toml workspace members, pyproject.toml/setup.cfg/__version__, package.json monorepo)

Progeneral

Performance

03
PF001-wasteful_roundtrip

Wasteful roundtrip

Transform-then-inverse patterns that waste CPU and memory (format! then slice, str then int)

Freegeneral
PF002-inline_regex_compilation

Inline regex compilation

Regex::new() with a static string literal inside a function body (compiled on every call)

Freeecosystem
PF003-inline_glob_compilation

Inline glob compilation

GlobSetBuilder::new() or GlobBuilder::new() inside a function body: glob compiled on every call instead of once

Proecosystem

Resource Loading

01
RL001-module_level_open

Module level open

Module-level open() calls with cwd-relative paths: breaks at import time when the process is not started from the project root

Proecosystem

Security

01
SE001-security_practices

Security practices

Dangerous API scanner: unsafe Rust (with missing/vague SAFETY comment detection), eval/exec/pickle in Python, innerHTML/eval/child_process in JavaScript

Freegeneral

Try the signal

Run the checks where your code already lives.

The Free CLI stays local and requires no account. Pro unlocks the complete entitled catalog for commercial work.