Skip to content

fix(deps): resolve missing source-imported packages from the component model on import - #10365

Merged
zkochan merged 3 commits into
teambit:masterfrom
zkochan:fix-missing-deps-from-model
Sep 1, 2026
Merged

fix(deps): resolve missing source-imported packages from the component model on import#10365
zkochan merged 3 commits into
teambit:masterfrom
zkochan:fix-missing-deps-from-model

Conversation

@zkochan

@zkochan zkochan commented May 12, 2026

Copy link
Copy Markdown
Member

Summary

  • When bit import brings in a component whose source requires a package, the dependency-tree walker can't resolve that package on disk (cold node_modules) and pushes it to missing.packages. processMissing then surfaces a MissingPackagesDependenciesOnFs issue — even though the imported component's model already records the package in packageDependencies.
  • processPackages already falls back to componentFromModel for resolved packages; this PR adds the same fallback in processMissing. If a "missing" package is listed in the model, move it into tree.packages with the model's recorded version so it enters the workspace manifest and gets installed by bit import — no follow-up bit install --add-missing-deps needed.
  • Truly-missing packages (not in workspace policy and not in the model) still surface as before.

Test plan

  • New e2e test e2e/harmony/import-resolves-missing-deps-from-model.e2e.ts covers the regression: a component requiring is-positive is tagged & exported, then imported in a fresh workspace; asserts that MissingPackagesDependenciesOnFs is not reported.
  • Verified the test fails on the prior code (issue surfaces) and passes with this fix.
…t model on import

When a freshly imported component requires a package that isn't yet in
node_modules, the dependency tree walker put it in missing.packages and
auto-detect surfaced MissingPackagesDependenciesOnFs. processPackages
already falls back to componentFromModel for resolved packages, but
processMissing didn't. Apply the same fallback: if the model records the
package in packageDependencies, move it into tree.packages with the
model's version so it enters the workspace manifest and gets installed
during bit import — no need for a follow-up bit install --add-missing-deps.
Copilot AI review requested due to automatic review settings May 12, 2026 11:52

Copilot AI left a comment

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.

Pull request overview

This PR fixes a false-positive MissingPackagesDependenciesOnFs issue during bit import when the imported component’s model already records the required package dependency, but the importing workspace’s node_modules is still “cold” at dependency-walk time. The change makes processMissing fall back to componentFromModel (similar to the existing behavior in processPackages) so model-recorded packages are treated as resolved and flow into the dependency tree.

Changes:

  • In AutoDetectDeps.processMissing, move “missing” packages into tree.packages when they exist in componentFromModel.getAllPackageDependencies(), preventing missing-package issues for those packages.
  • Add an E2E regression test that imports a component requiring is-positive into a fresh workspace (with --skip-dependency-installation) and asserts the missing-package issue is not reported.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
scopes/dependencies/dependencies/dependencies-loader/auto-detect-deps.ts Adds model-based fallback for packages initially classified as “missing” to avoid incorrect MissingPackagesDependenciesOnFs reporting on import.
e2e/harmony/import-resolves-missing-deps-from-model.e2e.ts Regression test covering import behavior when the model already lists a required package dependency.
@zkochan

zkochan commented May 12, 2026

Copy link
Copy Markdown
Member Author

Converting to draft. Verified against bit lane import bitdev.react/fix-react-peers-conflicts-full-scope that this PR is not required for that scenario — #10366 alone fixes it. Keeping this open as a narrower, independent correctness fix: in cases where a missing source-imported package is recorded in the component's model but on-disk resolution fails and it isn't installed via the scope's dependenciesGraph, this lets auto-detect treat it as resolved from the model. Not a release blocker; revisit when convenient.

zkochan added a commit that referenced this pull request May 12, 2026
…resolvePackageNameByPath (#10366)

## Summary
`pathNormalizeToLinux` (via `normalize-path`) already strips trailing
slashes, but the single-segment branch in `resolvePackageNameByPath`
returned the *original* (un-normalized) `packagePath`. So inputs like
`events/` leaked through unchanged.

That broke downstream matching: `MissingPackagesDependenciesOnFs`
reported the package as `events/`, while every other consumer —
workspace policy lookups, `resolvedPackageData.name` from
`resolvePackageData`, and the component model's `packageDependencies` —
uses the canonical name `events`. The trailing-slash form appears in
real-world code (most commonly webpack browser-fallback configs:
`require.resolve('events/')`), where it's used to force resolution to
the npm `events` polyfill rather than Node's builtin.

Returning the normalized path fixes the leak and aligns all consumers on
the canonical package name.

This is part of fixing the `bit lane import` symptom where a
webpack-bundler-style component reports `config/webpack-fallbacks.ts ->
events/` as a missing package: this PR makes the missing package surface
as `events` instead of `events/`. Together with #10365 (which lets
`processMissing` fall back to the component model when the model already
records the dep), the issue clears cleanly on import.

## Test plan
- [x] New e2e test
`e2e/harmony/missing-package-strips-trailing-slash.e2e.ts` asserts the
`MissingPackagesDependenciesOnFs` data records `events`, not `events/`,
for `require('events/')`.
- [x] Verified the test fails on the prior code (`expected [ 'events/' ]
to include 'events'`) and passes with the fix.
@zkochan
zkochan marked this pull request as ready for review September 1, 2026 12:28
@zkochan
zkochan enabled auto-merge (squash) September 1, 2026 12:29
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Resolve imported package dependencies from the component model

🐞 Bug fix 🧪 Tests 🕐 10-20 Minutes

Grey Divider

AI Description

• Resolve cold imports’ missing packages from dependencies recorded in the component model.
• Preserve issues for packages absent from both workspace policy and component model.
• Add end-to-end coverage for imports that skip dependency installation.
Diagram

sequenceDiagram
  actor User
  participant Import as Import Command
  participant Walker as Dependency Walker
  participant Detect as Auto Detect
  participant Model as Component Model
  participant Manifest as Workspace Manifest
  User->>Import: Import component
  Import->>Walker: Scan source imports
  Walker-->>Detect: Report missing package
  Detect->>Model: Read package dependencies
  Model-->>Detect: Return recorded version
  Detect->>Manifest: Add resolved package
  Detect-->>Import: Suppress false issue
Loading
High-Level Assessment

The localized fallback in processMissing is the preferred approach because it mirrors existing processPackages behavior, reuses authoritative model versions, and preserves reporting for genuinely unknown packages. Pre-installing dependencies before analysis would only mask the classification defect and introduce broader import-order coupling.

Files changed (2) +55 / -3

Bug fix (1) +15 / -3
auto-detect-deps.tsResolve disk-missing packages from component model metadata +15/-3

Resolve disk-missing packages from component model metadata

• Enhances missing-package processing to look up dependencies in the imported component model. Model-backed packages are moved into the dependency tree with their recorded versions, while unresolved packages continue producing missing-dependency issues.

scopes/dependencies/dependencies/dependencies-loader/auto-detect-deps.ts

Tests (1) +40 / -0
import-resolves-missing-deps-from-model.e2e.tsCover model-backed dependencies during cold imports +40/-0

Cover model-backed dependencies during cold imports

• Adds an end-to-end regression test that exports a component requiring is-positive, imports it without installing dependencies, and verifies that no MissingPackagesDependenciesOnFs issue is reported when the model records the package.

e2e/harmony/import-resolves-missing-deps-from-model.e2e.ts

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (1) 📜 Skill insights (0)

Grey Divider


Action required

1. Standalone import E2E duplicates area 📘 Rule violation ➹ Performance
Description
The PR creates a standalone E2E file even though import-harmony.e2e.ts already covers
import-without-install scenarios using the same workspace lifecycle. This unnecessarily fragments
the existing import test area and adds separate E2E setup overhead.
Code

e2e/harmony/import-resolves-missing-deps-from-model.e2e.ts[16]

+describe('bit import: missing-package issue suppressed when the model lists the package', function () {
Evidence
Rule 2 requires necessary E2E coverage to use an existing relevant E2E file where possible. The PR
introduces a new top-level import E2E suite, while import-harmony.e2e.ts already contains import
tests that create/export components, reinitialize the workspace, and call
importComponentWithoutInstall.

CLAUDE.md: Prefer Unit Tests and Minimize Necessary E2E Tests
e2e/harmony/import-resolves-missing-deps-from-model.e2e.ts[16-36]
e2e/harmony/import-harmony.e2e.ts[164-175]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The regression scenario was added as a new E2E file despite an existing E2E suite dedicated to Harmony import behavior.

## Issue Context
The scenario genuinely exercises workspace import behavior, but Compliance Rule 2 requires necessary E2E coverage to be added to an existing relevant file where possible. Move this focused scenario into `import-harmony.e2e.ts` and remove the standalone file while preserving its assertions and cleanup behavior.

## Fix Focus Areas
- e2e/harmony/import-resolves-missing-deps-from-model.e2e.ts[1-40]
- e2e/harmony/import-harmony.e2e.ts[164-175]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Peer model dependencies remain missing 🐞 Bug ≡ Correctness
Description
The new fallback checks only getAllPackageDependencies(), which excludes
peerPackageDependencies, so source imports of model-recorded peers remain in missing.packages
and still raise MissingPackagesDependenciesOnFs. This prevents the later peer-classification logic
from recovering the dependency because it only reclassifies packages already detected as runtime or
dev dependencies.
Code

scopes/dependencies/dependencies/dependencies-loader/auto-detect-deps.ts[R523-524]

+      if (this.componentFromModel) {
+        const modelDeps = this.componentFromModel.getAllPackageDependencies();
Evidence
The added filter removes only package names returned by getAllPackageDependencies, while that
helper merges runtime and dev maps only. Peer dependencies are explicitly supported as a separate
model field, and the downstream override stage can classify a detected package as a peer only if it
first exists in a runtime/dev package map; otherwise the added filter leaves it missing and line 533
reports it.

scopes/dependencies/dependencies/dependencies-loader/auto-detect-deps.ts[523-533]
components/legacy/consumer-component/consumer-component.ts[329-331]
components/legacy/consumer-component/consumer-component.ts[57-60]
scopes/dependencies/dependencies/dependencies-loader/apply-overrides.ts[458-480]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The missing-package fallback only consults `componentFromModel.getAllPackageDependencies()`, which includes runtime and dev dependencies but excludes peer package dependencies. An imported component requiring a model-recorded peer can therefore still receive `MissingPackagesDependenciesOnFs`.

## Issue Context
Peer dependencies are a separate model category. Once a package is placed into the detected runtime/dev package map, the existing override pipeline can reclassify it as a peer using the component model's package metadata.

## Fix Focus Areas
- scopes/dependencies/dependencies/dependencies-loader/auto-detect-deps.ts[523-530]
- components/legacy/consumer-component/consumer-component.ts[329-331]
- scopes/dependencies/dependencies/dependencies-loader/apply-overrides.ts[458-480]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can describe a rule in plain language on the Rules page and Qodo drafts it for you

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

// the bug by hoisting the package via the scope's dependenciesGraph) doesn't run. That makes
// the auto-detect path the only thing deciding whether the issue is reported, which is exactly
// the path the fix targets.
describe('bit import: missing-package issue suppressed when the model lists the package', function () {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Standalone import e2e duplicates area 📘 Rule violation ➹ Performance

The PR creates a standalone E2E file even though import-harmony.e2e.ts already covers
import-without-install scenarios using the same workspace lifecycle. This unnecessarily fragments
the existing import test area and adds separate E2E setup overhead.
Agent Prompt
## Issue description
The regression scenario was added as a new E2E file despite an existing E2E suite dedicated to Harmony import behavior.

## Issue Context
The scenario genuinely exercises workspace import behavior, but Compliance Rule 2 requires necessary E2E coverage to be added to an existing relevant file where possible. Move this focused scenario into `import-harmony.e2e.ts` and remove the standalone file while preserving its assertions and cleanup behavior.

## Fix Focus Areas
- e2e/harmony/import-resolves-missing-deps-from-model.e2e.ts[1-40]
- e2e/harmony/import-harmony.e2e.ts[164-175]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +523 to +524
if (this.componentFromModel) {
const modelDeps = this.componentFromModel.getAllPackageDependencies();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

2. Peer model dependencies remain missing 🐞 Bug ≡ Correctness

The new fallback checks only getAllPackageDependencies(), which excludes
peerPackageDependencies, so source imports of model-recorded peers remain in missing.packages
and still raise MissingPackagesDependenciesOnFs. This prevents the later peer-classification logic
from recovering the dependency because it only reclassifies packages already detected as runtime or
dev dependencies.
Agent Prompt
## Issue description
The missing-package fallback only consults `componentFromModel.getAllPackageDependencies()`, which includes runtime and dev dependencies but excludes peer package dependencies. An imported component requiring a model-recorded peer can therefore still receive `MissingPackagesDependenciesOnFs`.

## Issue Context
Peer dependencies are a separate model category. Once a package is placed into the detected runtime/dev package map, the existing override pipeline can reclassify it as a peer using the component model's package metadata.

## Fix Focus Areas
- scopes/dependencies/dependencies/dependencies-loader/auto-detect-deps.ts[523-530]
- components/legacy/consumer-component/consumer-component.ts[329-331]
- scopes/dependencies/dependencies/dependencies-loader/apply-overrides.ts[458-480]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (1) 📜 Skill insights (0)

Grey Divider


Action required

1. Model peers remain missing 🐞 Bug ≡ Correctness ⭐ New
Description
The fallback uses getAllPackageDependencies(), which excludes peerPackageDependencies, so a
source-imported peer absent from node_modules remains in missing.packages and raises
MissingPackagesDependenciesOnFs. It also never enters detected packages, preventing
applyPeersFromComponentModel() from restoring its peer classification and version.
Code

scopes/dependencies/dependencies/dependencies-loader/auto-detect-deps.ts[524]

+        const modelDeps = this.componentFromModel.getAllPackageDependencies();
Evidence
The new fallback filters missing names against getAllPackageDependencies(), but that method merges
only regular and dev maps. The later model-peer logic only converts names already present in
detected runtime/dev package maps, so an excluded peer stays missing and reaches the issue-reporting
branch.

scopes/dependencies/dependencies/dependencies-loader/auto-detect-deps.ts[517-533]
components/legacy/consumer-component/consumer-component.ts[329-331]
scopes/dependencies/dependencies/dependencies-loader/apply-overrides.ts[458-480]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Include model-recorded peer package dependencies when reconciling missing source imports, so valid peers do not remain missing on cold imports.

## Issue Context
`getAllPackageDependencies()` merges only runtime and dev package dependencies. Peer reclassification later operates only on packages already detected, so the fallback must seed model peers into `tree.packages` as well. Add regression coverage for a component that imports a model-recorded peer with an empty `node_modules`.

## Fix Focus Areas
- scopes/dependencies/dependencies/dependencies-loader/auto-detect-deps.ts[523-530]
- components/legacy/consumer-component/consumer-component.ts[329-331]
- scopes/dependencies/dependencies/dependencies-loader/apply-overrides.ts[458-480]
- e2e/harmony/import-resolves-missing-deps-from-model.e2e.ts[16-39]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Standalone import E2E duplicates area 📘 Rule violation ➹ Performance
Description
The PR creates a standalone E2E file even though import-harmony.e2e.ts already covers
import-without-install scenarios using the same workspace lifecycle. This unnecessarily fragments
the existing import test area and adds separate E2E setup overhead.
Code

e2e/harmony/import-resolves-missing-deps-from-model.e2e.ts[16]

+describe('bit import: missing-package issue suppressed when the model lists the package', function () {
Evidence
Rule 2 requires necessary E2E coverage to use an existing relevant E2E file where possible. The PR
introduces a new top-level import E2E suite, while import-harmony.e2e.ts already contains import
tests that create/export components, reinitialize the workspace, and call
importComponentWithoutInstall.

CLAUDE.md: Prefer Unit Tests and Minimize Necessary E2E Tests: CLAUDE.md: Prefer Unit Tests and Minimize Necessary E2E Tests
e2e/harmony/import-resolves-missing-deps-from-model.e2e.ts[16-36]
e2e/harmony/import-harmony.e2e.ts[164-175]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The regression scenario was added as a new E2E file despite an existing E2E suite dedicated to Harmony import behavior.
## Issue Context
The scenario genuinely exercises workspace import behavior, but Compliance Rule 2 requires necessary E2E coverage to be added to an existing relevant file where possible. Move this focused scenario into `import-harmony.e2e.ts` and remove the standalone file while preserving its assertions and cleanup behavior.
## Fix Focus Areas
- e2e/harmony/import-resolves-missing-deps-from-model.e2e.ts[1-40]
- e2e/harmony/import-harmony.e2e.ts[164-175]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. Peer model dependencies remain missing 🐞 Bug ≡ Correctness
Description
The new fallback checks only getAllPackageDependencies(), which excludes
peerPackageDependencies, so source imports of model-recorded peers remain in missing.packages
and still raise MissingPackagesDependenciesOnFs. This prevents the later peer-classification logic
from recovering the dependency because it only reclassifies packages already detected as runtime or
dev dependencies.
Code

scopes/dependencies/dependencies/dependencies-loader/auto-detect-deps.ts[R523-524]

+      if (this.componentFromModel) {
+        const modelDeps = this.componentFromModel.getAllPackageDependencies();
Evidence
The added filter removes only package names returned by getAllPackageDependencies, while that
helper merges runtime and dev maps only. Peer dependencies are explicitly supported as a separate
model field, and the downstream override stage can classify a detected package as a peer only if it
first exists in a runtime/dev package map; otherwise the added filter leaves it missing and line 533
reports it.

scopes/dependencies/dependencies/dependencies-loader/auto-detect-deps.ts[523-533]
components/legacy/consumer-component/consumer-component.ts[329-331]
components/legacy/consumer-component/consumer-component.ts[57-60]
scopes/dependencies/dependencies/dependencies-loader/apply-overrides.ts[458-480]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The missing-package fallback only consults `componentFromModel.getAllPackageDependencies()`, which includes runtime and dev dependencies but excludes peer package dependencies. An imported component requiring a model-recorded peer can therefore still receive `MissingPackagesDependenciesOnFs`.
## Issue Context
Peer dependencies are a separate model category. Once a package is placed into the detected runtime/dev package map, the existing override pipeline can reclassify it as a peer using the component model's package metadata.
## Fix Focus Areas
- scopes/dependencies/dependencies/dependencies-loader/auto-detect-deps.ts[523-530]
- components/legacy/consumer-component/consumer-component.ts[329-331]
- scopes/dependencies/dependencies/dependencies-loader/apply-overrides.ts[458-480]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can describe a rule in plain language on the Rules page and Qodo drafts it for you

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

// model's version so they end up in the workspace manifest and get installed — rather than
// surfacing as MissingPackagesDependenciesOnFs issues.
if (this.componentFromModel) {
const modelDeps = this.componentFromModel.getAllPackageDependencies();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Model peers remain missing 🐞 Bug ≡ Correctness

The fallback uses getAllPackageDependencies(), which excludes peerPackageDependencies, so a
source-imported peer absent from node_modules remains in missing.packages and raises
MissingPackagesDependenciesOnFs. It also never enters detected packages, preventing
applyPeersFromComponentModel() from restoring its peer classification and version.
Agent Prompt
## Issue description
Include model-recorded peer package dependencies when reconciling missing source imports, so valid peers do not remain missing on cold imports.

## Issue Context
`getAllPackageDependencies()` merges only runtime and dev package dependencies. Peer reclassification later operates only on packages already detected, so the fallback must seed model peers into `tree.packages` as well. Add regression coverage for a component that imports a model-recorded peer with an empty `node_modules`.

## Fix Focus Areas
- scopes/dependencies/dependencies/dependencies-loader/auto-detect-deps.ts[523-530]
- components/legacy/consumer-component/consumer-component.ts[329-331]
- scopes/dependencies/dependencies/dependencies-loader/apply-overrides.ts[458-480]
- e2e/harmony/import-resolves-missing-deps-from-model.e2e.ts[16-39]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@zkochan
zkochan merged commit eb9ce26 into teambit:master Sep 1, 2026
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

3 participants