Skip to content

cross-copy instanceof checks on error classes break when capsules host multiple copies of a package #10584

Description

@zkochan

Summary

Bit's error handling and model classes rely on instanceof across package boundaries, which silently breaks whenever two copies of the defining package coexist in one process. Build capsules make this easy to hit: a capsule network routinely contains multiple copies of @teambit packages (different versions, or the same version from different generations — see #10583).

Concrete example

component-status-loader.ts classifies load failures:

} catch (err: any) {
  if (err instanceof ComponentNotFoundInPath || err instanceof MissingBitMapComponent) {
    if (componentFromModel) status.deleted = true;
    ...

When the loader that throws and the status loader that catches resolve ComponentNotFoundInPath from different copies, the instanceof is false and the error escapes as fatal. Observed effect (diagnosed on CI during #10582): a freshly tagged component with its directory present reported {deleted: true} / tolerant recovery paths (checkout reset, staged detection) turned into hard crashes.

Suggested direction

For error classes at least, match on a stable discriminator instead of (or in addition to) instanceof — e.g. err.name / a code property / BitError.isBitError(err, 'ComponentNotFoundInPath') helper — the same pattern Node ecosystem libraries use for exactly this reason. The status-loader catch above and its siblings (ComponentsPendingImport, etc.) are the highest-value call sites; a repo-wide sweep of instanceof <ErrorClass> on cross-package classes would find the rest.

Found while diagnosing #10583, where mixed-generation capsules made this class of failure deterministic. Fixing this would defang that bug's symptom independently of the lane fix.

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions