Skip to content

fix(core): break filesystem/search import cycle - #48877

Open
benrfairless wants to merge 1 commit into
anomalyco:devfrom
benrfairless:fix/filesystem-search-import-cycle
Open

benrfairless wants to merge 1 commit into
anomalyco:devfrom
benrfairless:fix/filesystem-search-import-cycle

Conversation

@benrfairless

Copy link
Copy Markdown

Issue for this PR

Closes #48876

Type of change

  • Bug fix

What does this PR do?

core/src/filesystem.ts and core/src/filesystem/search.ts import each other, and filesystem.ts:117 dereferences the other module at evaluation time:

deps: [FSUtil.node, Location.node, FileSystemSearch.node]

search.ts never needs it that early. Its only runtime uses are FileSystem.Entry.make and FileSystem.Match.make; the other three are type positions. Entry and Match already live in @opencode-ai/schema/filesystem, which filesystem.ts imports them from and re-exports. So this imports them from there directly in search.ts and makes the remaining FileSystem import import type, which is erased. The runtime edge back to filesystem.ts is gone, so there is no cycle and evaluation order stops mattering.

Why it matters: with the cycle present, a bundler that emits search.ts's body after filesystem.ts's body leaves FileSystemSearch.node undefined in that array, and the layer graph carries an undefined dependency until something walks it. Bun 1.4.2 does exactly that, so 1.18.30 built with it fails on every prompt with TypeError: undefined is not an object (evaluating 'a.name'). I have reported the ordering behaviour separately as oven-sh/bun#42664, but the cycle is worth removing either way, since it makes us rely on the bundler picking the one order that works.

No behaviour change: same schema classes, same .make calls, imported from where they are defined.

How did you verify your code works?

On this branch, with Bun 1.4.2 on macOS 27:

  • bun run typecheck in packages/core - exit 0
  • bun test test/filesystem/search.test.ts - 2 pass, 0 fail
  • bun --bun ./script/build.ts --single --skip-install - builds, smoke test passes
  • Ran the resulting binary with a real prompt - it replies normally. The same build from dev fails on every prompt with the TypeError above, so this is the change that fixes it.

I also reduced the bundler behaviour to a three-file repro (in oven-sh/bun#42664): unbundled, Bun raises ReferenceError: Cannot access 'node' before initialization, which is the correct answer; bundled, it silently yields undefined.

Screenshots / recordings

n/a, not a UI change.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

AI disclosure: I used Claude Code (model claude-opus-5) to investigate the crash and prepare this change. I reviewed the diff and ran the verification above myself.

@github-actions

Copy link
Copy Markdown
Contributor

Hey! Your PR title Break filesystem and search import cycle doesn't follow conventional commit format.

Please update it to start with one of:

  • feat: or feat(scope): new feature
  • fix: or fix(scope): bug fix
  • docs: or docs(scope): documentation changes
  • chore: or chore(scope): maintenance tasks
  • refactor: or refactor(scope): code refactoring
  • test: or test(scope): adding or updating tests

Where scope is the package name (e.g., app, desktop, opencode).

See CONTRIBUTING.md for details.

@github-actions

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

Found potentially related PRs:

  1. fix(core): reject undefined layer node dependencies #48818 - fix(core): reject undefined layer node dependencies

  2. fix(core): break filesystem cycle in compiled prompts #48397 - fix(core): break filesystem cycle in compiled prompts

    • Related because it also addresses breaking filesystem cycles, potentially in a similar area of the codebase.

These PRs may be addressing the same or overlapping issues around the filesystem import cycle and undefined dependencies that occur with certain bundler configurations (Bun 1.4.2).

filesystem.ts and filesystem/search.ts import each other, and
filesystem.ts dereferences the other module at evaluation time in a
top-level deps array. search.ts never needs it that early: its only
runtime uses are FileSystem.Entry.make and FileSystem.Match.make, and
its three remaining uses are type positions.

Entry and Match already live in @opencode-ai/schema/filesystem, which
filesystem.ts imports them from and re-exports. Import them from there
directly, and make the remaining FileSystem import type-only so it is
erased. That removes the runtime edge back to filesystem.ts, so the
cycle is gone and module evaluation order no longer matters.

With the cycle present, a bundler that emits search.ts after
filesystem.ts leaves FileSystemSearch.node undefined in that deps
array, and the layer graph then fails on first use with
"TypeError: undefined is not an object (evaluating 'a.name')".
Bun 1.4.2 does exactly that, reported as oven-sh/bun#42664.

Closes anomalyco#48876

Assisted-by: Claude Code:claude-opus-5
@benrfairless
benrfairless force-pushed the fix/filesystem-search-import-cycle branch from a0cfbf2 to 7f392ba Compare September 14, 2026 00:09
@benrfairless benrfairless changed the title Break filesystem and search import cycle fix(core): break filesystem/search import cycle Sep 14, 2026
attilaolah added a commit to attilaolah/os that referenced this pull request Sep 14, 2026
attilaolah added a commit to attilaolah/os that referenced this pull request Sep 15, 2026
* Update dependency anomalyco/opencode to v1.18.30

* chore(opencode): update flake lock

* fix: patch model-router for opencode 1.18.29+ support

* fix: opencode npm deps hash

* fix: patch opencode, remove model-router patch

Adds a fetchpatch to pull anomalyco/opencode#48877.

* fix: patch hash

* fix: make hashes platform dependent

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Attila Oláh <attila@dorn.haus>
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.

Circular import between core/src/filesystem.ts and core/src/filesystem/search.ts leaves an undefined layer dependency

1 participant