Skip to content

fix(cli): skip npm install in protobuf IR generation when packages already installed#12326

Closed
thesandlord wants to merge 4 commits intomainfrom
devin/1770963732-fix-protobuf-ir-airgap
Closed

fix(cli): skip npm install in protobuf IR generation when packages already installed#12326
thesandlord wants to merge 4 commits intomainfrom
devin/1770963732-fix-protobuf-ir-airgap

Conversation

@thesandlord
Copy link
Copy Markdown
Contributor

@thesandlord thesandlord commented Feb 13, 2026

Description

Refs: Customer report of gRPC generation hanging in air-gapped self-hosted environments.

In ProtobufIRGenerator.setupRemainingProtobufConfig(), two npm install calls (npm install for @bufbuild/protobuf+@bufbuild/protoplugin, and npm install -g fern-api) ran unconditionally. In air-gapped environments where npm cannot reach the registry, these calls hang indefinitely — the root cause of gRPC generation freezing in self-hosted deployments.

This PR uses the existing this.isAirGapped flag as the primary guard to skip all npm installs in air-gapped mode (where the self-hosted Docker image already has fern-api globally and @bufbuild packages at /opt/buf-modules). For non-air-gapped environments, package availability is checked before installing as a secondary optimization.

Additionally, the air-gapped detection timeout (detectAirGappedModeForProtobuf) is reduced from 30s to 10s to minimize startup delay in air-gapped environments.

Requested by: @thesandlord
Link to Devin run: https://app.devin.ai/sessions/a5880378995e43e5bc32210f77dcac83

Changes Made

  • Air-gapped primary guard: When this.isAirGapped is true, all npm installs are skipped entirely with a debug log message
  • Added isModuleResolvable() — checks if a package exists in the working directory's node_modules via fs.stat (used in non-air-gapped path)
  • Added isPackageInstalledGlobally() — checks if a package is globally installed via npm list -g (used in non-air-gapped path)
  • In non-air-gapped mode, setupRemainingProtobufConfig skips npm install / npm install -g fern-api if the packages are already present
  • Reduced air-gap detection timeout from 30s to 10s in detectAirGappedModeForProtobuf() (utils.ts)
  • Updated versions.yml with v3.76.1 changelog entry
  • Updated README.md generator (if applicable) — N/A

⚠️ Items for Human Review

  1. isAirGapped is only set when deps.length > 0: In generateLocal(), air-gap detection via detectAirGappedModeForProtobuf only runs when there are buf dependencies. If a protobuf spec has no deps but the environment is air-gapped, this.isAirGapped remains undefined and npm install will still be attempted. In practice, gRPC specs should always have deps — but reviewers should confirm this assumption holds.

  2. isModuleResolvable on temp directory: In the non-air-gapped path, the check runs against a freshly created temp directory that won't have node_modules, so it will almost always fall through to running npm install. This is acceptable behavior for non-air-gapped environments but means the check is effectively a no-op optimization. The air-gapped guard is the real fix.

  3. Docker npm wrapper interaction: The self-hosted Docker image already has an npm wrapper that intercepts npm install calls for @bufbuild packages and copies from /opt/buf-modules/node_modules. If the wrapper were working correctly, the hang shouldn't occur — suggesting the wrapper may be bypassed in some scenarios (PATH ordering, permissions, etc.). This code-level fix provides defense-in-depth.

  4. 10s detection timeout: The reduced timeout should be sufficient for a network connectivity check, but very slow or high-latency networks could false-positive as air-gapped. Previously this was 30s.

Testing

  • Unit tests added/updated
  • Manual testing completed — lint passes (pnpm run check)

…ready installed

Co-Authored-By: Sandeep Dinesh <sandeep@buildwithfern.com>
@devin-ai-integration
Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@github-actions
Copy link
Copy Markdown
Contributor

🌱 Seed Test Selector

Select languages to run seed tests for:

  • Python
  • TypeScript
  • Java
  • Go
  • Ruby
  • C#
  • PHP
  • Swift
  • Rust
  • OpenAPI
  • Postman

How to use: Click the ⋯ menu above → "Edit" → check the boxes you want → click "Update comment". Tests will run automatically and snapshots will be committed to this PR.

devin-ai-integration Bot and others added 3 commits February 13, 2026 06:27
…n air-gapped mode

Co-Authored-By: Sandeep Dinesh <sandeep@buildwithfern.com>
Co-Authored-By: Sandeep Dinesh <sandeep@buildwithfern.com>
Co-Authored-By: Sandeep Dinesh <sandeep@buildwithfern.com>
@github-actions
Copy link
Copy Markdown
Contributor

This PR is stale because it has been open 25 days with no activity. Remove stale label or comment or this will be closed in 5 days.

@github-actions github-actions Bot added the Stale This PR hasn't has any commits or comments in 25 days or more. label Mar 11, 2026
@github-actions
Copy link
Copy Markdown
Contributor

This PR was closed because it has been inactive for 5 days after being marked stale.

@github-actions github-actions Bot closed this Mar 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Stale This PR hasn't has any commits or comments in 25 days or more.

Development

Successfully merging this pull request may close these issues.

1 participant