Skip to content

Anti-patterns

A grep target for code review. Every load-bearing rule restated as a code-review trigger, with a link to the page that explains why.

A grep target. When reviewing a PR, scan for any of the patterns below and link the relevant row in your review. Each row links to the page with the full reasoning.

Don’t Why See
Shell out to netlab directly. Bypasses logging, error handling, expected_failure, the stream toggle. Async discipline → Single Netlab invocation path
Do blocking I/O in an async handler without _run_blocking. Stalls the event loop; every poll from every other client backs up. Async discipline
Add async code to the atexit teardown. No event loop at exit; deadlocks the interpreter. atexit + lifespan
Drop the *Dto suffix on a request/response model. Convention is load-bearing for code review and reasoning. Invariants → *Dto suffix
Remove a # CVE-* comment on a dependency upgrade. Pin reasoning is silent metadata; deletion regresses the security gate. Invariants → CVE-pinned dependencies
Run two neops-remote-lab servers on the same host. Filelock catches it, but only after both processes log noise; the underlying constraint is real. Invariants → One server instance per host
Run netlab by hand while the server is running. State divergence; the server’s default instance and your manual one collide. Invariants → One lab per host
Call acquire (the polling variant) from inside the server’s event loop. Loop blocks; release that would unblock you cannot land. LabManager → try_acquire vs acquire
Add code to LabManager or connector.py that imports asyncio. Crosses the sync/async boundary the other direction; no benefit, fragile teardown. Async discipline
Add a topology-accepting entry point that doesn’t accept both .yml and .yaml. Surface asymmetry; “topology accepted, then mysteriously rejected” failures. Invariants → .yml and .yaml are both accepted
Add a second auth path (Bearer, mTLS, header magic) without removing the X-Session-ID gate. Confused threat model; callers get to choose which boundary to bypass. Invariants → X-Session-ID is the only access boundary
Write a test that depends on stub-only behaviour and passes in CI. Stub diverges from real Netlab at the boundary; the test hides the divergence. CI test stubbing

See also