Skip to content

fix(windows): handle empty payloads when npm is not present - #129

Merged
ashishkurmi merged 2 commits into
step-security:mainfrom
swarit-stepsecurity:swarit/fix/empty-payload
Jun 4, 2026
Merged

ashishkurmi merged 2 commits into
step-security:mainfrom
swarit-stepsecurity:swarit/fix/empty-payload

Conversation

@swarit-stepsecurity

Copy link
Copy Markdown
Member

What does this PR do?

Type of change

  • Bug fix
  • Enhancement
  • Documentation

Testing

  • Tested on macOS (version: ___)
  • Binary runs without errors: ./stepsecurity-dev-machine-guard --verbose
  • JSON output is valid: ./stepsecurity-dev-machine-guard --json | python3 -m json.tool
  • No secrets or credentials included
  • Lint passes: make lint
  • Tests pass: make test

Related Issues

Copilot AI left a comment

Copy link
Copy Markdown

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 prevents Windows (and other platforms) from emitting misleading/empty Node.js project scan telemetry when the detected package manager binary (e.g., npm) is not present on PATH, and adds clearer operator-facing logging for the “no PMs installed” scenario.

Changes:

  • Add a per-scanner cache for package-manager binary availability and skip per-project telemetry emission when the PM binary is missing.
  • Improve per-project scan error reporting by preserving runInDir execution errors (instead of deriving errors only from exit codes).
  • Add/adjust tests to cover the “PM not in PATH” regression, record-dropping behavior, and the PATH lookup cache; add a telemetry warning when no Node package managers are detected.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 7 comments.

File Description
internal/telemetry/telemetry.go Adds a warning when Node.js package managers detection returns empty to make the “no PMs installed” state visible.
internal/detector/nodescan.go Adds cached binary availability checks, changes scanProject to return (result, ok) and drops records when the PM binary is absent; preserves execution errors.
internal/detector/nodescan_test.go Updates existing tests for the new scanProject signature and adds regression/behavior tests for missing PMs and caching.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread internal/telemetry/telemetry.go Outdated
Comment on lines +711 to +713
// the per-project scans about to run would all ENOENT and ship
// empty stdout records. Output.log from cfacorp prod showed this
// blank on every broken device; the warning makes the root cause
Comment thread internal/telemetry/telemetry.go Outdated
// blank on every broken device; the warning makes the root cause
// visible at the agent level.
if len(pkgManagers) == 0 {
log.Warn("No Node.js package managers found on PATH — per-project scans will be skipped")
Comment thread internal/detector/nodescan.go Outdated
Comment on lines +45 to +49
// for the lifetime of a single ScanProjects call. On a device with 700+
// lockfiles, the per-project scan path previously paid a PATH lookup
// per project; this cache collapses that to one lookup per distinct
// PM. Also avoided: spamming the same "x not found in PATH" warning
// hundreds of times when the PM truly isn't installed.
Comment thread internal/detector/nodescan.go Outdated

// binaryAvailable returns the cached checkPath result for a package-manager
// binary, populating the cache on first call. Wraps checkPath so callers in
// the per-project loop don't pay an LookPath per project on devices that
Comment thread internal/detector/nodescan.go Outdated
Comment on lines +429 to +433
@@ -405,7 +430,12 @@ func (s *NodeScanner) ScanProjects(ctx context.Context, searchDirs []string) []m
pm := DetectProjectPM(s.exec, p.dir)
s.log.Progress(" Package manager: %s", pm)

r := s.scanProject(ctx, p.dir)
r, ok := s.scanProject(ctx, p.dir)
Comment thread internal/detector/nodescan_test.go Outdated
}
}

// TestNodeScanner_ScanProject_PMNotInPATH covers the cfacorp regression:
Comment thread internal/detector/nodescan_test.go Outdated
Comment on lines +409 to +410
// records. This is what cfacorp's broken devices needed.
func TestNodeScanner_ScanProjects_DropsRecordsForMissingPM(t *testing.T) {
Signed-off-by: Swarit Pandey <[email protected]>
@swarit-stepsecurity swarit-stepsecurity changed the title fix(windows): handle empty payloads when npn is not present fix(windows): handle empty payloads when npm is not present Jun 4, 2026
@ashishkurmi
ashishkurmi merged commit 745ef4d into step-security:main Jun 4, 2026
11 checks passed
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