-
-
Notifications
You must be signed in to change notification settings - Fork 832
Description
Summary
oxlint import/no-cycle can miss a real cycle depending only on sibling filename/traversal order.
I can reproduce a deterministic false negative where:
- Case A reports 0 diagnostics
- Case B (same graph shape, only renaming
aaaInternal.ts->zzzInternal.ts) reports the expected 3 cycle diagnostics
This looks like traversal-order sensitivity, likely interacting with a type-only import path.
Environment
- oxlint:
1.42.0 - Node:
v22.20.0 - OS:
Darwin 24.6.0 arm64
Repro
Create this file tree:
src/manager/balanceSweepDetailsManager.ts
import { installmentLoanManager } from './installmentLoanManager'
import { aaaInternal } from './aaaInternal'
export const balanceSweepDetailsManager = {
call(): string {
return installmentLoanManager.call() + aaaInternal.call()
},
}src/manager/installmentLoanManager.ts
import { getAvenAccountData } from './dataReport/avenAccountDataReportManager'
export type installType = { x: number }
export const installmentLoanManager = { call: () => getAvenAccountData() }src/manager/dataReport/avenAccountDataReportManager.ts
import { balanceSweepDetailsManager } from '../balanceSweepDetailsManager'
export const getAvenAccountData = (): string => String(Boolean(balanceSweepDetailsManager))src/manager/simpleInterestLoanManager.ts
import type { installType } from './installmentLoanManager'
export const simpleInterestLoanManager = { call: (): string => String(Boolean(null as installType | null)) }src/manager/aaaInternal.ts
import { simpleInterestLoanManager } from './simpleInterestLoanManager'
export const aaaInternal = { call: () => simpleInterestLoanManager.call() }Run:
oxlint --import-plugin -A all -D no-cycle -f json srcActual (Case A)
diagnostics.length = 0
Expected
Should report the cycle:
balanceSweepDetailsManager -> installmentLoanManager -> dataReport/avenAccountDataReportManager -> balanceSweepDetailsManager
Filename-only rename flips behavior
Rename only:
src/manager/aaaInternal.ts->src/manager/zzzInternal.ts- update the import in
balanceSweepDetailsManager.ts
Run the same command again.
Actual (Case B)
diagnostics.length = 3, with files:
src/manager/balanceSweepDetailsManager.tssrc/manager/installmentLoanManager.tssrc/manager/dataReport/avenAccountDataReportManager.ts
Notes
I also reproduced this pattern in a larger codebase. The minimal repro above is deterministic on my machine.