Skip to content

fix: disallow circular project references#686

Open
no-yan wants to merge 2 commits intooxc-project:mainfrom
no-yan:fix/circular-project-references
Open

fix: disallow circular project references#686
no-yan wants to merge 2 commits intooxc-project:mainfrom
no-yan:fix/circular-project-references

Conversation

@no-yan
Copy link
Copy Markdown
Collaborator

@no-yan no-yan commented Feb 15, 2026

Summary

Improves parsing performance by disabling UseSourceOfProjectReference and adds proper error handling for circular project references.

Background

Previously, we enabled UseSourceOfProjectReference to fix panics caused by circular project references (#574). However, this option forces the parser to use source files instead of declaration files, which is inherently slow.

Furthermore, upstream TypeScript and Tsgo don't support circular project references.
Indeed, running tsgo -b (build mode) on #574's repro produces this error.

Rather than supporting this case, we now detect circular references and emit a clear diagnostic to guide users.

Benchmark

1.29 times faster on aws-cdk

Details

Benchmark 1: trunk
  Time (mean ± σ):      7.260 s ±  0.252 s    [User: 32.910 s, System: 4.898 s]
  Range (min … max):    6.997 s …  7.500 s    3 runs

  Warning: Ignoring non-zero exit code.

Benchmark 2: baseline
  Time (mean ± σ):      9.396 s ±  0.150 s    [User: 41.610 s, System: 7.114 s]
  Range (min … max):    9.243 s …  9.542 s    3 runs

  Warning: Ignoring non-zero exit code.

Summary
  trunk ran
    1.29 ± 0.05 times faster than baseline

Note

Disclosure: I used some AI tools: Codex for implement my plan and gemini for improve my english.

…king

Circular project references are not supported by TypeScript specification.
Previously, we worked around this by using UseSourceOfProjectReference to
include all source files, but this was incorrect. Now we properly detect
circular project references and emit a diagnostic error instead of panicking.
@no-yan no-yan force-pushed the fix/circular-project-references branch from a3a39be to 37dd987 Compare February 15, 2026 17:13
for _, f := range unmatchedFiles {
onInternalDiagnostic(diagnostic.Internal{
Id: "circular-project-references",
Description: fmt.Sprintf("File was not found in program '%s'. This is likely caused by circular project references, which are not supported by TypeScript (TS6202).", configFileName),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why doesn't the tsconfig parsing/ error matching produce this error code?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. This error appears only in "build mode" (tsgo -b).
  2. Since tsgolint does not use build mode, this error will not occur.

The reason of 1 is likely because references are a no-op in non-"build" mode.
It remains unclear why files are missing from the program created by tsgolint; there can be an issue within find_tsconfig.go.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I investigated find_tsconfig.go and confirmed it works correctly. It maps files to the right tsconfig even with circular project references.

Copy link
Copy Markdown
Contributor

@camc314 camc314 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little confused here since the typechecking in the original repro worked?

@rubnogueira
Copy link
Copy Markdown

I was notified since you commented in my other post, but I'm not following your PR.

While I understand that when I run with tsc -b may face circular reference errors, would it mean that it would throw an error for such cases with tsgolint?

@no-yan
Copy link
Copy Markdown
Collaborator Author

no-yan commented Feb 16, 2026

@rubnogueira
Yes, exactly. Instead of crashing, I plan to display clear error message.

@rubnogueira
Copy link
Copy Markdown

rubnogueira commented Feb 16, 2026

I'm not following. Since eslint/typescript-eslint works perfectly, why the need for tsgolint to display an error message and behave differently?

@no-yan
Copy link
Copy Markdown
Collaborator Author

no-yan commented Feb 16, 2026

Thanks for the feedback.

I’m proposing this change because circular references are likely configuration errors.

Project References are option which is used to speed up build.
However, circular dependencies prevent us from running tsgo -b. This means there is no way to achieve the intended build speedup.

If there are valid use cases for composite projects with circular refs that I'm missing, please let me know. I'd love to hear your thoughts!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants