Skip to content

Conversation

@justin808
Copy link
Member

@justin808 justin808 commented Nov 13, 2025

Summary

Adds proactive doctor checks to detect :async loading strategy usage in projects without React on Rails Pro, which can cause component registration race conditions.

Changes

The doctor now checks for and reports errors when it detects:

  • javascript_pack_tag with :async in view files
  • config.generated_component_packs_loading_strategy = :async in initializer

When detected without Pro, provides clear guidance to either upgrade to Pro or use :defer/:sync loading strategies.

This complements PR #1993's configuration validation by adding runtime detection during development to help developers identify and fix async usage issues.

Testing

All new tests pass (155+ examples in doctor spec). The checks are skipped when React on Rails Pro is installed.


This change is Reviewable

Summary by CodeRabbit

  • New Features

    • Added a diagnostic that detects use of async component loading when the Pro edition isn't present, lists affected locations, and offers guidance and upgrade options.
  • Tests

    • Expanded tests covering detection across view templates and initializer settings, including comment-aware scanning, multi-format template support, error handling, and skipping checks when Pro is installed.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 13, 2025

Walkthrough

Adds development diagnostics to detect use of async script loading in view templates and in config/initializers/react_on_rails.rb, reporting file paths and guidance when React on Rails Pro is not installed.

Changes

Cohort / File(s) Summary
Async Usage Detection Feature
lib/react_on_rails/doctor.rb
Added check_async_usage (called from check_development) and helpers: scan_view_files_for_async_pack_tag, scan_pattern_for_async, file_has_async_pack_tag?, content_has_only_commented_async?, config_has_async_loading_strategy?, relativize_path, and log_debug. Scans app/views/**/*.erb and app/views/**/*.haml, parses config/initializers/react_on_rails.rb, handles file-scan errors, and reports errors when :async is used without Pro.
Async Detection Test Suite
spec/lib/react_on_rails/doctor_spec.rb
Added specs for #check_async_usage (skips with Pro; errors without), scan_view_files_for_async_pack_tag (ERB/Haml/multi-line/defer/comment cases), and config_has_async_loading_strategy? (detects :async, ignores commented lines, distinguishes :defer).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Dev as check_development
  participant Doctor as ReactOnRails::Doctor
  participant FS as File system (views + initializer)
  participant Reporter as Reporter (add_error/noop)
  rect rgba(0,128,128,0.06)
  Dev ->> Doctor: invoke check_async_usage
  Doctor ->> Doctor: return if Pro installed
  alt Pro installed
    Doctor ->> Reporter: skip async checks (noop)
  else Pro not installed
    Doctor ->> FS: scan_view_files_for_async_pack_tag()
    FS -->> Doctor: list of view files with active async tags
    Doctor ->> FS: config_has_async_loading_strategy?()
    FS -->> Doctor: boolean (initializer uses :async?)
    alt any async detected (views or config)
      Doctor ->> Reporter: add_error(details: file paths, config lines, guidance)
    else none detected
      Doctor ->> Reporter: noop
    end
  end
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Files/areas needing attention:
    • Regex and comment-handling in file_has_async_pack_tag? and content_has_only_commented_async?.
    • Path relativization and error handling in scan_pattern_for_async / scan_view_files_for_async_pack_tag.
    • Edge cases and false-positives for config_has_async_loading_strategy? (commented lines, different quoting, whitespace).

Possibly related PRs

Poem

🐇 I hop through views with careful eye,

I sniff async tags that sneak and fly.
If Pro's not near I gently shout,
Point the files that should be checked out.
A little doctor rabbit on the route.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: adding doctor checks to detect :async usage in projects without React on Rails Pro.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch justin808/doctor-check-async-requires-pro

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@claude
Copy link

claude bot commented Nov 13, 2025

Code Review - PR #2010: Add doctor checks for :async usage without React on Rails Pro

Summary

This PR adds proactive detection of :async loading strategy usage in projects without React on Rails Pro, helping developers identify configuration issues that can cause component registration race conditions. The implementation is solid and well-tested.

Strengths

  1. Excellent Test Coverage - 156 new test examples covering all scenarios including Pro installed vs not installed, both detection methods (view files and initializer), and edge cases (missing files, exceptions)

  2. Consistent Code Quality - Follows existing patterns in the Doctor class with proper error handling, clear informative error messages, and early returns for clarity

  3. User Experience - Clear error messages with emoji indicators, provides concrete solutions (upgrade to Pro OR use :defer/:sync), links to documentation, and shows specific file paths where issues are detected

  4. Integration - Properly integrated into check_development workflow, consistent with other doctor checks, and skips check when Pro is installed (no false positives)

Potential Issues and Suggestions

1. Regex Pattern Potential Edge Cases (Minor)

Location: lib/react_on_rails/doctor.rb:1195

The regex patterns may miss some edge cases like commented code, multi-line calls, or hash syntax variations (async: true). Consider using the /m flag to match newlines and handle more variations.

2. Performance Consideration (Low Priority)

Location: lib/react_on_rails/doctor.rb:1183-1204

Reads entire file contents into memory for each view file. For large projects this could be slow, but since doctor checks run on-demand (not in hot path), current implementation is acceptable. Only optimize if users report performance issues.

3. Configuration File Detection (Minor Edge Case)

Location: lib/react_on_rails/doctor.rb:1206-1215

Only checks config/initializers/react_on_rails.rb. Some projects might use different initializer filenames or configure in config/environments/development.rb. Not critical since standard name is well-documented.

4. Test Coverage Gap (Minor)

Tests cover async in views only, async in config only, and no async usage. Missing test case for async in BOTH views AND config simultaneously.

Security and Performance

Security: No concerns identified - reads files from known safe locations, no user input execution, proper exception handling

Performance: Acceptable - doctor checks run on-demand, file globbing efficient for typical Rails apps, early returns prevent unnecessary work

Final Assessment

Overall Quality: Excellent (5/5)

Recommendation: APPROVE with optional minor enhancements

The code is production-ready as-is. All identified issues are minor edge cases that do not block merging. This PR demonstrates thorough testing (156 examples), clear documentation, consistent code quality, helpful user experience, and proper integration with existing systems.

Great work!

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
lib/react_on_rails/doctor.rb (2)

1151-1181: Consider adding top-level error handling.

The method logic is sound and correctly checks for async usage without Pro. However, consider wrapping the entire method body in a rescue clause to ensure that any unexpected errors during scanning don't break the entire doctor run.

Apply this diff to add defensive error handling:

 def check_async_usage
   # When Pro is installed, async is fully supported and is the default behavior
   # No need to check for async usage in this case
   return if ReactOnRails::Utils.react_on_rails_pro?

   async_issues = []

   # Check 1: javascript_pack_tag with :async in view files
   view_files_with_async = scan_view_files_for_async_pack_tag
   unless view_files_with_async.empty?
     async_issues << "javascript_pack_tag with :async found in view files:"
     view_files_with_async.each do |file|
       async_issues << "  • #{file}"
     end
   end

   # Check 2: generated_component_packs_loading_strategy = :async
   if config_has_async_loading_strategy?
     async_issues << "config.generated_component_packs_loading_strategy = :async in initializer"
   end

   return if async_issues.empty?

   # Report errors if async usage is found without Pro
   checker.add_error("🚫 :async usage detected without React on Rails Pro")
   async_issues.each { |issue| checker.add_error("  #{issue}") }
   checker.add_info("  💡 :async can cause race conditions. Options:")
   checker.add_info("    1. Upgrade to React on Rails Pro (recommended for :async support)")
   checker.add_info("    2. Change to :defer or :sync loading strategy")
   checker.add_info("  📖 https://www.shakacode.com/react-on-rails/docs/guides/configuration/")
+rescue StandardError => e
+  checker.add_warning("⚠️  Could not complete async usage check: #{e.message}")
+  Rails.logger.debug("Async usage check error: #{e.full_message}") if defined?(Rails) && Rails.logger
 end

1209-1224: Note potential edge case with multi-line comments.

The comment filtering logic correctly handles single-line comments in ERB, HAML, and HTML. However, it may not correctly handle multi-line scenarios:

  1. Multi-line ERB tags split across lines
  2. Multi-line HTML comments wrapping ERB tags

These edge cases are rare in practice, but if false positives occur, consider using a more sophisticated parsing approach or documenting this limitation.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 044d7de and 8382e94.

📒 Files selected for processing (2)
  • lib/react_on_rails/doctor.rb (2 hunks)
  • spec/lib/react_on_rails/doctor_spec.rb (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • spec/lib/react_on_rails/doctor_spec.rb
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1875
File: lib/react_on_rails/utils.rb:112-124
Timestamp: 2025-10-23T17:22:01.074Z
Learning: In React on Rails, when Pro is installed but not licensed, the intended behavior is to raise an error on boot. The `react_on_rails_pro?` method validates licenses and should raise errors early (including during path resolution in methods like `server_bundle?`) to enforce licensing requirements rather than failing later with obscure errors.
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1781
File: node_package/src/ClientSideRenderer.ts:82-95
Timestamp: 2025-09-15T21:24:48.207Z
Learning: In React on Rails, the force_load feature includes both explicit `data-force-load="true"` usage and the ability to hydrate components during the page loading state (`document.readyState === 'loading'`). Both capabilities require a Pro license, so the condition `!railsContext.rorPro && (isComponentForceLoaded || document.readyState === 'loading')` correctly gates both scenarios.
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: lib/react_on_rails/helper.rb:190-197
Timestamp: 2025-02-18T13:08:01.477Z
Learning: RSC support validation in React on Rails Pro is handled through a chain of validations:
1. Pro version check in `run_stream_inside_fiber`
2. RSC support check during pack generation via `ReactOnRailsPro.configuration.enable_rsc_support`
3. RSC support validation during component registration
This makes additional validation in the helper methods unnecessary.
Learnt from: alexeyr-ci
Repo: shakacode/react_on_rails PR: 1644
File: node_package/src/ReactOnRailsRSC.ts:87-87
Timestamp: 2024-12-12T13:07:09.929Z
Learning: When handling errors in 'node_package/src/ReactOnRailsRSC.ts', include the error stack in error messages in development and test environments to aid debugging.
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: node_package/src/turbolinksUtils.ts:34-36
Timestamp: 2025-02-13T16:50:26.861Z
Learning: In React on Rails, when checking for Turbolinks version 5 using `turbolinksVersion5()`, always ensure `Turbolinks` exists first by checking `turbolinksInstalled()` to prevent TypeError when accessing properties.
Learnt from: Romex91
Repo: shakacode/react_on_rails PR: 1697
File: package-scripts.yml:28-28
Timestamp: 2025-02-12T16:38:06.537Z
Learning: The file `node_package/lib/ReactOnRails.full.js` is autogenerated during the build process and should not be present in the repository.
📚 Learning: 2025-10-23T17:22:01.074Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1875
File: lib/react_on_rails/utils.rb:112-124
Timestamp: 2025-10-23T17:22:01.074Z
Learning: In React on Rails, when Pro is installed but not licensed, the intended behavior is to raise an error on boot. The `react_on_rails_pro?` method validates licenses and should raise errors early (including during path resolution in methods like `server_bundle?`) to enforce licensing requirements rather than failing later with obscure errors.

Applied to files:

  • lib/react_on_rails/doctor.rb
📚 Learning: 2025-02-18T13:08:01.477Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: lib/react_on_rails/helper.rb:190-197
Timestamp: 2025-02-18T13:08:01.477Z
Learning: RSC support validation in React on Rails Pro is handled through a chain of validations:
1. Pro version check in `run_stream_inside_fiber`
2. RSC support check during pack generation via `ReactOnRailsPro.configuration.enable_rsc_support`
3. RSC support validation during component registration
This makes additional validation in the helper methods unnecessary.

Applied to files:

  • lib/react_on_rails/doctor.rb
📚 Learning: 2025-09-15T21:24:48.207Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1781
File: node_package/src/ClientSideRenderer.ts:82-95
Timestamp: 2025-09-15T21:24:48.207Z
Learning: In React on Rails, the force_load feature includes both explicit `data-force-load="true"` usage and the ability to hydrate components during the page loading state (`document.readyState === 'loading'`). Both capabilities require a Pro license, so the condition `!railsContext.rorPro && (isComponentForceLoaded || document.readyState === 'loading')` correctly gates both scenarios.

Applied to files:

  • lib/react_on_rails/doctor.rb
📚 Learning: 2024-12-12T13:07:09.929Z
Learnt from: alexeyr-ci
Repo: shakacode/react_on_rails PR: 1644
File: node_package/src/ReactOnRailsRSC.ts:87-87
Timestamp: 2024-12-12T13:07:09.929Z
Learning: When handling errors in 'node_package/src/ReactOnRailsRSC.ts', include the error stack in error messages in development and test environments to aid debugging.

Applied to files:

  • lib/react_on_rails/doctor.rb
📚 Learning: 2025-02-13T16:50:26.861Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: node_package/src/turbolinksUtils.ts:34-36
Timestamp: 2025-02-13T16:50:26.861Z
Learning: In React on Rails, when checking for Turbolinks version 5 using `turbolinksVersion5()`, always ensure `Turbolinks` exists first by checking `turbolinksInstalled()` to prevent TypeError when accessing properties.

Applied to files:

  • lib/react_on_rails/doctor.rb
🧬 Code graph analysis (1)
lib/react_on_rails/doctor.rb (2)
lib/react_on_rails/utils.rb (1)
  • react_on_rails_pro? (256-264)
lib/react_on_rails/system_checker.rb (2)
  • add_error (16-18)
  • add_info (28-30)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build
  • GitHub Check: claude-review
🔇 Additional comments (3)
lib/react_on_rails/doctor.rb (3)

176-176: LGTM!

The integration of check_async_usage into the development checks flow is well-placed and follows the existing pattern.


1183-1191: LGTM!

Good error handling for file scanning operations. The method appropriately catches file and encoding errors, logs them for debugging, and returns an empty array to prevent the doctor run from failing.


1226-1240: LGTM!

The config checking logic is sound:

  • Correctly filters out commented lines while preserving lines with inline comments (which should still be flagged if they set async)
  • Proper regex pattern with flexible whitespace handling
  • Appropriate error handling with debug logging

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
lib/react_on_rails/doctor.rb (1)

1221-1247: Consider clarifying multi-line tag comment detection behavior.

The method filters out commented async usage by checking if lines containing javascript_pack_tag are commented. For multi-line tags, this checks the opening line containing javascript_pack_tag. While the comment on line 1230 explains this, the behavior means that a tag like:

<%= javascript_pack_tag "app",
  :async %>

is considered uncommented (correctly), but

<%# javascript_pack_tag "app",
  :async %>

is considered commented (correctly). The implementation is sound, but you might consider adding a test case explicitly documenting the expected behavior for edge cases like when the opening tag is uncommented but contains only the method name, with :async on a subsequent line within the same ERB block.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8382e94 and 9f6dc24.

📒 Files selected for processing (2)
  • lib/react_on_rails/doctor.rb (2 hunks)
  • spec/lib/react_on_rails/doctor_spec.rb (1 hunks)
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1875
File: lib/react_on_rails/utils.rb:112-124
Timestamp: 2025-10-23T17:22:01.074Z
Learning: In React on Rails, when Pro is installed but not licensed, the intended behavior is to raise an error on boot. The `react_on_rails_pro?` method validates licenses and should raise errors early (including during path resolution in methods like `server_bundle?`) to enforce licensing requirements rather than failing later with obscure errors.
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1781
File: node_package/src/ClientSideRenderer.ts:82-95
Timestamp: 2025-09-15T21:24:48.207Z
Learning: In React on Rails, the force_load feature includes both explicit `data-force-load="true"` usage and the ability to hydrate components during the page loading state (`document.readyState === 'loading'`). Both capabilities require a Pro license, so the condition `!railsContext.rorPro && (isComponentForceLoaded || document.readyState === 'loading')` correctly gates both scenarios.
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: lib/react_on_rails/helper.rb:190-197
Timestamp: 2025-02-18T13:08:01.477Z
Learning: RSC support validation in React on Rails Pro is handled through a chain of validations:
1. Pro version check in `run_stream_inside_fiber`
2. RSC support check during pack generation via `ReactOnRailsPro.configuration.enable_rsc_support`
3. RSC support validation during component registration
This makes additional validation in the helper methods unnecessary.
Learnt from: alexeyr-ci
Repo: shakacode/react_on_rails PR: 1644
File: node_package/src/ReactOnRailsRSC.ts:87-87
Timestamp: 2024-12-12T13:07:09.929Z
Learning: When handling errors in 'node_package/src/ReactOnRailsRSC.ts', include the error stack in error messages in development and test environments to aid debugging.
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: node_package/src/turbolinksUtils.ts:34-36
Timestamp: 2025-02-13T16:50:26.861Z
Learning: In React on Rails, when checking for Turbolinks version 5 using `turbolinksVersion5()`, always ensure `Turbolinks` exists first by checking `turbolinksInstalled()` to prevent TypeError when accessing properties.
Learnt from: Romex91
Repo: shakacode/react_on_rails PR: 1697
File: package-scripts.yml:28-28
Timestamp: 2025-02-12T16:38:06.537Z
Learning: The file `node_package/lib/ReactOnRails.full.js` is autogenerated during the build process and should not be present in the repository.
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: node_package/src/clientStartup.ts:18-21
Timestamp: 2025-02-13T16:50:47.848Z
Learning: In the react_on_rails module, the `reactOnRailsPageUnloaded` function in clientStartup.ts is intentionally kept private as it's only used internally as a callback for `onPageUnloaded`.
📚 Learning: 2025-10-23T17:22:01.074Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1875
File: lib/react_on_rails/utils.rb:112-124
Timestamp: 2025-10-23T17:22:01.074Z
Learning: In React on Rails, when Pro is installed but not licensed, the intended behavior is to raise an error on boot. The `react_on_rails_pro?` method validates licenses and should raise errors early (including during path resolution in methods like `server_bundle?`) to enforce licensing requirements rather than failing later with obscure errors.

Applied to files:

  • spec/lib/react_on_rails/doctor_spec.rb
  • lib/react_on_rails/doctor.rb
📚 Learning: 2025-02-18T13:08:01.477Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: lib/react_on_rails/helper.rb:190-197
Timestamp: 2025-02-18T13:08:01.477Z
Learning: RSC support validation in React on Rails Pro is handled through a chain of validations:
1. Pro version check in `run_stream_inside_fiber`
2. RSC support check during pack generation via `ReactOnRailsPro.configuration.enable_rsc_support`
3. RSC support validation during component registration
This makes additional validation in the helper methods unnecessary.

Applied to files:

  • spec/lib/react_on_rails/doctor_spec.rb
  • lib/react_on_rails/doctor.rb
📚 Learning: 2025-09-15T21:24:48.207Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1781
File: node_package/src/ClientSideRenderer.ts:82-95
Timestamp: 2025-09-15T21:24:48.207Z
Learning: In React on Rails, the force_load feature includes both explicit `data-force-load="true"` usage and the ability to hydrate components during the page loading state (`document.readyState === 'loading'`). Both capabilities require a Pro license, so the condition `!railsContext.rorPro && (isComponentForceLoaded || document.readyState === 'loading')` correctly gates both scenarios.

Applied to files:

  • spec/lib/react_on_rails/doctor_spec.rb
  • lib/react_on_rails/doctor.rb
📚 Learning: 2024-12-12T13:07:09.929Z
Learnt from: alexeyr-ci
Repo: shakacode/react_on_rails PR: 1644
File: node_package/src/ReactOnRailsRSC.ts:87-87
Timestamp: 2024-12-12T13:07:09.929Z
Learning: When handling errors in 'node_package/src/ReactOnRailsRSC.ts', include the error stack in error messages in development and test environments to aid debugging.

Applied to files:

  • lib/react_on_rails/doctor.rb
📚 Learning: 2025-02-13T16:50:26.861Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: node_package/src/turbolinksUtils.ts:34-36
Timestamp: 2025-02-13T16:50:26.861Z
Learning: In React on Rails, when checking for Turbolinks version 5 using `turbolinksVersion5()`, always ensure `Turbolinks` exists first by checking `turbolinksInstalled()` to prevent TypeError when accessing properties.

Applied to files:

  • lib/react_on_rails/doctor.rb
🧬 Code graph analysis (1)
lib/react_on_rails/doctor.rb (2)
lib/react_on_rails/utils.rb (1)
  • react_on_rails_pro? (256-264)
lib/react_on_rails/system_checker.rb (2)
  • add_error (16-18)
  • add_info (28-30)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: lint-js-and-ruby
  • GitHub Check: build-dummy-app-webpack-test-bundles
  • GitHub Check: build-dummy-app-webpack-test-bundles
  • GitHub Check: build
  • GitHub Check: claude-review
🔇 Additional comments (8)
spec/lib/react_on_rails/doctor_spec.rb (3)

192-268: Excellent test coverage for async usage detection.

The test suite comprehensively covers the Pro-aware behavior, async detection in views and config, and the absence of async usage. The structure is clear and properly isolated with mocks.


270-410: Thorough testing of view file scanning with edge cases.

The tests cover various syntax forms (:async, async: true), false positive prevention (defer: "async"), comment scenarios across ERB/HAML/HTML, and multi-line tag handling. This comprehensive coverage ensures the scanner behaves correctly across different template formats.


412-458: Complete config strategy detection test coverage.

The tests validate detection of :async strategy, differentiation from other strategies (:defer), handling of missing config files, and proper filtering of commented-out configuration. This ensures robust config file parsing.

lib/react_on_rails/doctor.rb (5)

176-176: Good integration of async check into development diagnostics.

The new check_async_usage method is appropriately placed in the development checks section, ensuring it runs during normal doctor diagnosis.


1151-1181: Well-implemented Pro-aware async usage validation.

The implementation correctly:

  • Skips validation when Pro is installed (async is supported)
  • Aggregates findings from both view files and config
  • Reports clear error messages with actionable guidance
  • Provides documentation links for resolution

The early return for Pro installations prevents false positives and aligns with the learning that Pro features should be validated through proper channels.

Based on learnings


1183-1203: Robust view file scanning with proper error handling.

The implementation scans both ERB and HAML templates, filters out commented usage, relativizes paths for display, and includes appropriate error handling for file system and encoding issues. The use of Rails.logger.debug for error logging is appropriate for a diagnostic tool.


1205-1219: Regex pattern correctly addresses past review feedback.

The single regex pattern /javascript_pack_tag[^<]*(?::async\b|async:\s*true)/ correctly matches:

  • :async symbol syntax
  • async: true hash syntax

The pattern appropriately avoids false positives like defer: "async" (where "async" is a string value, not the async option). The use of word boundary \b and the [^<]* construct for matching within ERB tags handles multi-line tags correctly.

The past review comment regarding the overly broad second regex pattern has been properly addressed in commit 9f6dc24.


1249-1268: Solid config detection with appropriate filtering.

The method correctly:

  • Filters out commented lines before checking for :async strategy
  • Uses word boundary \b to match the complete symbol, not partial matches like :async_mode
  • Includes error handling for file system and encoding errors
  • Returns false on errors (safe default)

The implementation properly detects the async loading strategy while avoiding false positives from commented configuration.

justin808 and others added 3 commits November 13, 2025 14:28
Adds proactive detection of :async loading strategy usage in projects
without React on Rails Pro, which can cause component registration race
conditions.

The doctor now checks for:
1. javascript_pack_tag with :async in view files
2. config.generated_component_packs_loading_strategy = :async in initializer

When detected without Pro, provides clear guidance:
- Upgrade to React on Rails Pro (recommended)
- Change to :defer or :sync loading strategy

This complements PR #1993's configuration validation by adding runtime
doctor checks that help users identify and fix async usage issues during
development.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Addressed code review feedback to make the async usage detection more
robust and accurate:

1. Enhanced error handling:
   - Replace broad StandardError catches with specific exceptions
     (Errno::ENOENT, Encoding::InvalidByteSequenceError,
     Encoding::UndefinedConversionError)
   - Add debug logging when errors occur (if Rails logger available)

2. Add comment filtering to reduce false positives:
   - Filter out commented Ruby lines in config files (lines starting with #)
   - Skip ERB comments (<%# ... %>), HAML comments (-# ...), and HTML
     comments (<!-- ... -->) in view files
   - Prevent false alarms from commented-out code

3. Refactor for code quality:
   - Extract scan_pattern_for_async and file_has_async_pack_tag? helpers
   - Reduce cyclomatic complexity in scan_view_files_for_async_pack_tag
   - All RuboCop checks pass

4. Expand test coverage:
   - Add tests for ERB, HAML, and HTML comment scenarios
   - Add test for commented config with async strategy
   - All 13 async-related tests pass

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…nsive tests

- Remove overly broad string form regex that could cause false positives
- Add support for both :async symbol and async: true hash syntax
- Add word boundary \b to prevent matching :async_mode or similar
- Improve multi-line javascript_pack_tag detection
- Add comprehensive inline documentation with examples
- Add test for async: true pattern detection
- Add test to confirm defer: "async" does not trigger false positive
- Add test for multi-line javascript_pack_tag calls
- Improve comment filtering logic to handle multi-line tags correctly
- Use String#include? for better performance (RuboCop compliance)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@justin808 justin808 force-pushed the justin808/doctor-check-async-requires-pro branch from 9f6dc24 to 4cdff17 Compare November 14, 2025 00:28
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9f6dc24 and 4cdff17.

📒 Files selected for processing (2)
  • lib/react_on_rails/doctor.rb (2 hunks)
  • spec/lib/react_on_rails/doctor_spec.rb (1 hunks)
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1875
File: lib/react_on_rails/utils.rb:112-124
Timestamp: 2025-10-23T17:22:01.074Z
Learning: In React on Rails, when Pro is installed but not licensed, the intended behavior is to raise an error on boot. The `react_on_rails_pro?` method validates licenses and should raise errors early (including during path resolution in methods like `server_bundle?`) to enforce licensing requirements rather than failing later with obscure errors.
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1781
File: node_package/src/ClientSideRenderer.ts:82-95
Timestamp: 2025-09-15T21:24:48.207Z
Learning: In React on Rails, the force_load feature includes both explicit `data-force-load="true"` usage and the ability to hydrate components during the page loading state (`document.readyState === 'loading'`). Both capabilities require a Pro license, so the condition `!railsContext.rorPro && (isComponentForceLoaded || document.readyState === 'loading')` correctly gates both scenarios.
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: lib/react_on_rails/helper.rb:190-197
Timestamp: 2025-02-18T13:08:01.477Z
Learning: RSC support validation in React on Rails Pro is handled through a chain of validations:
1. Pro version check in `run_stream_inside_fiber`
2. RSC support check during pack generation via `ReactOnRailsPro.configuration.enable_rsc_support`
3. RSC support validation during component registration
This makes additional validation in the helper methods unnecessary.
Learnt from: alexeyr-ci
Repo: shakacode/react_on_rails PR: 1644
File: node_package/src/ReactOnRailsRSC.ts:87-87
Timestamp: 2024-12-12T13:07:09.929Z
Learning: When handling errors in 'node_package/src/ReactOnRailsRSC.ts', include the error stack in error messages in development and test environments to aid debugging.
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: node_package/src/turbolinksUtils.ts:34-36
Timestamp: 2025-02-13T16:50:26.861Z
Learning: In React on Rails, when checking for Turbolinks version 5 using `turbolinksVersion5()`, always ensure `Turbolinks` exists first by checking `turbolinksInstalled()` to prevent TypeError when accessing properties.
Learnt from: Romex91
Repo: shakacode/react_on_rails PR: 1697
File: package-scripts.yml:28-28
Timestamp: 2025-02-12T16:38:06.537Z
Learning: The file `node_package/lib/ReactOnRails.full.js` is autogenerated during the build process and should not be present in the repository.
📚 Learning: 2025-10-23T17:22:01.074Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1875
File: lib/react_on_rails/utils.rb:112-124
Timestamp: 2025-10-23T17:22:01.074Z
Learning: In React on Rails, when Pro is installed but not licensed, the intended behavior is to raise an error on boot. The `react_on_rails_pro?` method validates licenses and should raise errors early (including during path resolution in methods like `server_bundle?`) to enforce licensing requirements rather than failing later with obscure errors.

Applied to files:

  • lib/react_on_rails/doctor.rb
  • spec/lib/react_on_rails/doctor_spec.rb
📚 Learning: 2025-02-18T13:08:01.477Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: lib/react_on_rails/helper.rb:190-197
Timestamp: 2025-02-18T13:08:01.477Z
Learning: RSC support validation in React on Rails Pro is handled through a chain of validations:
1. Pro version check in `run_stream_inside_fiber`
2. RSC support check during pack generation via `ReactOnRailsPro.configuration.enable_rsc_support`
3. RSC support validation during component registration
This makes additional validation in the helper methods unnecessary.

Applied to files:

  • lib/react_on_rails/doctor.rb
  • spec/lib/react_on_rails/doctor_spec.rb
📚 Learning: 2025-09-15T21:24:48.207Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1781
File: node_package/src/ClientSideRenderer.ts:82-95
Timestamp: 2025-09-15T21:24:48.207Z
Learning: In React on Rails, the force_load feature includes both explicit `data-force-load="true"` usage and the ability to hydrate components during the page loading state (`document.readyState === 'loading'`). Both capabilities require a Pro license, so the condition `!railsContext.rorPro && (isComponentForceLoaded || document.readyState === 'loading')` correctly gates both scenarios.

Applied to files:

  • lib/react_on_rails/doctor.rb
  • spec/lib/react_on_rails/doctor_spec.rb
📚 Learning: 2024-12-12T13:07:09.929Z
Learnt from: alexeyr-ci
Repo: shakacode/react_on_rails PR: 1644
File: node_package/src/ReactOnRailsRSC.ts:87-87
Timestamp: 2024-12-12T13:07:09.929Z
Learning: When handling errors in 'node_package/src/ReactOnRailsRSC.ts', include the error stack in error messages in development and test environments to aid debugging.

Applied to files:

  • lib/react_on_rails/doctor.rb
📚 Learning: 2025-02-13T16:50:26.861Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: node_package/src/turbolinksUtils.ts:34-36
Timestamp: 2025-02-13T16:50:26.861Z
Learning: In React on Rails, when checking for Turbolinks version 5 using `turbolinksVersion5()`, always ensure `Turbolinks` exists first by checking `turbolinksInstalled()` to prevent TypeError when accessing properties.

Applied to files:

  • lib/react_on_rails/doctor.rb
🧬 Code graph analysis (1)
lib/react_on_rails/doctor.rb (2)
lib/react_on_rails/utils.rb (1)
  • react_on_rails_pro? (256-264)
lib/react_on_rails/system_checker.rb (2)
  • add_error (16-18)
  • add_info (28-30)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build
  • GitHub Check: claude-review
🔇 Additional comments (9)
lib/react_on_rails/doctor.rb (6)

176-176: LGTM!

The integration of check_async_usage into the development checks flow is well-placed and consistent with other diagnostic checks.


1151-1181: LGTM!

The check_async_usage method correctly implements the Pro feature gate and provides clear, actionable error messages with guidance. The early return when Pro is installed is appropriate, and the aggregation of issues before reporting is well-structured.


1183-1191: LGTM!

Robust error handling with appropriate fallback behavior for a diagnostic tool. The debug logging helps troubleshooting without cluttering output.


1193-1203: LGTM!

The filtering logic is efficient and correctly skips files where async is only in comments. Using filter_map is a good choice for combining filter and map operations.


1205-1219: Well-crafted regex pattern with excellent documentation.

The regex correctly matches both :async symbol and async: true hash syntax while avoiding false positives. The word boundary \b ensures it doesn't match longer symbols like :async_mode. The documented theoretical edge case data: { async: true } is acceptable as it would only produce a harmless warning in extremely unlikely scenarios.


1249-1268: LGTM!

The config detection logic correctly filters out commented lines and uses word boundaries to ensure precise matching. Error handling with debug logging is appropriate for a diagnostic tool.

spec/lib/react_on_rails/doctor_spec.rb (3)

192-268: LGTM!

Comprehensive test coverage for the Pro/non-Pro branching and async detection in both view files and initializer config. The tests correctly verify error reporting and the no-issue scenarios.


270-410: Good test coverage for common scenarios.

The tests comprehensively cover detection of :async symbol, async: true hash syntax, false positive prevention for defer: "async", various comment styles (ERB, HAML, HTML), and multi-line tags.

Note: Additional test coverage is needed for the false positive scenario identified in the implementation review (uncommented javascript_pack_tag without :async coexisting with commented :async).


412-458: LGTM!

Complete test coverage for all branches of config_has_async_loading_strategy?, including the :async detection, different strategies, missing file, and commented-out configuration scenarios.

Extract comment pattern regexes to named constants for better
maintainability and reusability. Add defensive log_debug helper
method to safely handle Rails.logger access.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4cdff17 and cda9a31.

📒 Files selected for processing (1)
  • lib/react_on_rails/doctor.rb (2 hunks)
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1875
File: lib/react_on_rails/utils.rb:112-124
Timestamp: 2025-10-23T17:22:01.074Z
Learning: In React on Rails, when Pro is installed but not licensed, the intended behavior is to raise an error on boot. The `react_on_rails_pro?` method validates licenses and should raise errors early (including during path resolution in methods like `server_bundle?`) to enforce licensing requirements rather than failing later with obscure errors.
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1781
File: node_package/src/ClientSideRenderer.ts:82-95
Timestamp: 2025-09-15T21:24:48.207Z
Learning: In React on Rails, the force_load feature includes both explicit `data-force-load="true"` usage and the ability to hydrate components during the page loading state (`document.readyState === 'loading'`). Both capabilities require a Pro license, so the condition `!railsContext.rorPro && (isComponentForceLoaded || document.readyState === 'loading')` correctly gates both scenarios.
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: lib/react_on_rails/helper.rb:190-197
Timestamp: 2025-02-18T13:08:01.477Z
Learning: RSC support validation in React on Rails Pro is handled through a chain of validations:
1. Pro version check in `run_stream_inside_fiber`
2. RSC support check during pack generation via `ReactOnRailsPro.configuration.enable_rsc_support`
3. RSC support validation during component registration
This makes additional validation in the helper methods unnecessary.
Learnt from: alexeyr-ci
Repo: shakacode/react_on_rails PR: 1644
File: node_package/src/ReactOnRailsRSC.ts:87-87
Timestamp: 2024-12-12T13:07:09.929Z
Learning: When handling errors in 'node_package/src/ReactOnRailsRSC.ts', include the error stack in error messages in development and test environments to aid debugging.
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: node_package/src/turbolinksUtils.ts:34-36
Timestamp: 2025-02-13T16:50:26.861Z
Learning: In React on Rails, when checking for Turbolinks version 5 using `turbolinksVersion5()`, always ensure `Turbolinks` exists first by checking `turbolinksInstalled()` to prevent TypeError when accessing properties.
Learnt from: justin808
Repo: shakacode/react_on_rails PR: 1770
File: lib/generators/react_on_rails/templates/base/base/app/javascript/src/HelloWorld/ror_components/HelloWorld.client.jsx:2-2
Timestamp: 2025-09-16T08:01:11.146Z
Learning: React on Rails uses webpack CSS Modules configuration with namedExports: true, which requires the import syntax `import * as style from './file.module.css'` rather than the default export pattern. This configuration enables better tree shaking and bundle size optimization for CSS modules.
Learnt from: alexeyr-ci2
Repo: shakacode/react_on_rails PR: 1732
File: spec/dummy/client/app-react16/startup/ReduxSharedStoreApp.client.jsx:40-44
Timestamp: 2025-04-26T21:55:55.874Z
Learning: In the react_on_rails project, files under `app-react16` directories are copied/moved to corresponding `/app` directories during the conversion process (removing the `-react16` suffix), which affects their relative import paths at runtime.
Learnt from: Romex91
Repo: shakacode/react_on_rails PR: 1697
File: package-scripts.yml:28-28
Timestamp: 2025-02-12T16:38:06.537Z
Learning: The file `node_package/lib/ReactOnRails.full.js` is autogenerated during the build process and should not be present in the repository.
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: node_package/src/clientStartup.ts:18-21
Timestamp: 2025-02-13T16:50:47.848Z
Learning: In the react_on_rails module, the `reactOnRailsPageUnloaded` function in clientStartup.ts is intentionally kept private as it's only used internally as a callback for `onPageUnloaded`.
📚 Learning: 2025-02-18T13:08:01.477Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: lib/react_on_rails/helper.rb:190-197
Timestamp: 2025-02-18T13:08:01.477Z
Learning: RSC support validation in React on Rails Pro is handled through a chain of validations:
1. Pro version check in `run_stream_inside_fiber`
2. RSC support check during pack generation via `ReactOnRailsPro.configuration.enable_rsc_support`
3. RSC support validation during component registration
This makes additional validation in the helper methods unnecessary.

Applied to files:

  • lib/react_on_rails/doctor.rb
📚 Learning: 2025-10-23T17:22:01.074Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1875
File: lib/react_on_rails/utils.rb:112-124
Timestamp: 2025-10-23T17:22:01.074Z
Learning: In React on Rails, when Pro is installed but not licensed, the intended behavior is to raise an error on boot. The `react_on_rails_pro?` method validates licenses and should raise errors early (including during path resolution in methods like `server_bundle?`) to enforce licensing requirements rather than failing later with obscure errors.

Applied to files:

  • lib/react_on_rails/doctor.rb
📚 Learning: 2025-09-15T21:24:48.207Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1781
File: node_package/src/ClientSideRenderer.ts:82-95
Timestamp: 2025-09-15T21:24:48.207Z
Learning: In React on Rails, the force_load feature includes both explicit `data-force-load="true"` usage and the ability to hydrate components during the page loading state (`document.readyState === 'loading'`). Both capabilities require a Pro license, so the condition `!railsContext.rorPro && (isComponentForceLoaded || document.readyState === 'loading')` correctly gates both scenarios.

Applied to files:

  • lib/react_on_rails/doctor.rb
📚 Learning: 2025-04-26T21:55:55.874Z
Learnt from: alexeyr-ci2
Repo: shakacode/react_on_rails PR: 1732
File: spec/dummy/client/app-react16/startup/ReduxSharedStoreApp.client.jsx:40-44
Timestamp: 2025-04-26T21:55:55.874Z
Learning: In the react_on_rails project, files under `app-react16` directories are copied/moved to corresponding `/app` directories during the conversion process (removing the `-react16` suffix), which affects their relative import paths at runtime.

Applied to files:

  • lib/react_on_rails/doctor.rb
📚 Learning: 2024-12-12T13:07:09.929Z
Learnt from: alexeyr-ci
Repo: shakacode/react_on_rails PR: 1644
File: node_package/src/ReactOnRailsRSC.ts:87-87
Timestamp: 2024-12-12T13:07:09.929Z
Learning: When handling errors in 'node_package/src/ReactOnRailsRSC.ts', include the error stack in error messages in development and test environments to aid debugging.

Applied to files:

  • lib/react_on_rails/doctor.rb
📚 Learning: 2025-02-13T16:50:26.861Z
Learnt from: AbanoubGhadban
Repo: shakacode/react_on_rails PR: 1644
File: node_package/src/turbolinksUtils.ts:34-36
Timestamp: 2025-02-13T16:50:26.861Z
Learning: In React on Rails, when checking for Turbolinks version 5 using `turbolinksVersion5()`, always ensure `Turbolinks` exists first by checking `turbolinksInstalled()` to prevent TypeError when accessing properties.

Applied to files:

  • lib/react_on_rails/doctor.rb
🧬 Code graph analysis (1)
lib/react_on_rails/doctor.rb (2)
lib/react_on_rails/utils.rb (1)
  • react_on_rails_pro? (256-264)
lib/react_on_rails/system_checker.rb (2)
  • add_error (16-18)
  • add_info (28-30)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build
  • GitHub Check: claude-review
🔇 Additional comments (7)
lib/react_on_rails/doctor.rb (7)

1151-1154: LGTM! Well-organized comment pattern constants.

The comment patterns for ERB, HAML, and HTML are clearly defined and properly support the filtering logic used later in the async detection.


1156-1186: LGTM! Well-structured async usage detection.

The method correctly:

  • Skips checks when Pro is installed (async is fully supported)
  • Aggregates issues from both view files and config
  • Provides clear error messages with actionable guidance
  • Links to relevant documentation

1188-1196: LGTM! Robust file scanning with appropriate error handling.

The method properly scans ERB and HAML files, handles file system and encoding errors gracefully, and logs issues for debugging.


1198-1208: LGTM! Clean file processing logic.

The method correctly filters files by checking for uncommented async usage and returns relativized paths for better readability.


1210-1224: LGTM! Well-designed regex pattern with clear documentation.

The regex correctly matches both :async symbol and async: true hash syntax while using word boundaries to avoid false positives. The [^<]* pattern properly handles multi-line tags within ERB blocks, and the comment thoroughly explains edge cases.


1254-1273: LGTM! Correct config parsing with proper comment filtering.

The method correctly:

  • Checks file existence before reading
  • Filters out commented lines
  • Uses word boundary to match the complete :async symbol
  • Handles errors gracefully with safe fallback

1275-1279: LGTM! Clean logging helper with proper guards.

The method safely logs debug messages only when Rails.logger is available, preventing errors in environments where logging may not be configured.

Comment on lines +1226 to +1252
def content_has_only_commented_async?(content)
# Check if all occurrences of javascript_pack_tag with :async are in comments
# Returns true if ONLY commented async usage exists (no active async usage)
# Note: We need to check the full content first (for multi-line tags) before line-by-line filtering

# First check if there's any javascript_pack_tag with :async in the full content
return true unless file_has_async_pack_tag?(content)

# Now check line-by-line to see if all occurrences are commented
# For multi-line tags, we check if the starting line is commented
has_uncommented_async = content.each_line.any? do |line|
# Skip lines that don't contain javascript_pack_tag
next unless line.include?("javascript_pack_tag")

# Skip ERB comments (<%# ... %>)
next if line.match?(ERB_COMMENT_PATTERN)
# Skip HAML comments (-# ...)
next if line.match?(HAML_COMMENT_PATTERN)
# Skip HTML comments (<!-- ... -->)
next if line.match?(HTML_COMMENT_PATTERN)

# If we reach here, this line has an uncommented javascript_pack_tag
true
end

!has_uncommented_async
end
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical false positive bug: line 1238 doesn't verify :async presence.

The current logic produces false positives when a file has an uncommented javascript_pack_tag without :async alongside a commented one with :async.

Example scenario causing false positive:

<%= javascript_pack_tag "app", defer: true %>
<%# javascript_pack_tag "other", :async %>

Current behavior: Reports async usage (false positive)
Expected behavior: Should not report (only :async is commented)

Root cause: Line 1238 checks line.include?("javascript_pack_tag") but doesn't verify the line contains :async, so any uncommented pack tag triggers detection even when it has no async option.

Apply this fix:

     has_uncommented_async = content.each_line.any? do |line|
-      # Skip lines that don't contain javascript_pack_tag
-      next unless line.include?("javascript_pack_tag")
+      # Skip lines that don't contain javascript_pack_tag with :async
+      next unless file_has_async_pack_tag?(line)

       # Skip ERB comments (<%# ... %>)
       next if line.match?(ERB_COMMENT_PATTERN)

This ensures only lines with both javascript_pack_tag AND async indicators are considered, eliminating false positives.

Note: This issue was previously flagged in past review comments but remains unfixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants