Skip to content

feat: add early module import validation for JavaScript/TypeScript#1756

Open
aseembits93 wants to merge 2 commits intomainfrom
fix/early-module-import-validation-js
Open

feat: add early module import validation for JavaScript/TypeScript#1756
aseembits93 wants to merge 2 commits intomainfrom
fix/early-module-import-validation-js

Conversation

@aseembits93
Copy link
Contributor

Summary

  • Adds pre-flight validation to the JS/TS optimizer: before making expensive AI API calls, checks whether the source file is within the configured moduleRoot
  • If misconfigured, auto-corrects by inferring the module root from package.json fields and directory conventions (src/, lib/, etc.), and writes the corrected value back to package.json
  • Mirrors the existing Python module import validation pattern

Changes

  • New: codeflash/code_utils/config_js_validation.pyvalidate_js_module_resolution() and infer_js_module_root() utilities
  • Modified: codeflash/languages/javascript/function_optimizer.py — Added try_correct_module_root() and can_be_optimized() override to JavaScriptFunctionOptimizer
  • New: tests/code_utils/test_config_js_validation.py — 10 unit tests for validation utilities
  • New: tests/test_languages/test_js_function_optimizer_validation.py — 6 integration tests for optimizer methods

Test plan

  • uv run pytest tests/code_utils/test_config_js_validation.py -v — 10/10 pass
  • uv run pytest tests/test_languages/test_js_function_optimizer_validation.py -v — 6/6 pass
  • uv run pytest tests/test_languages/test_javascript_test_runner.py -v — 29/29 pass (no regressions)
  • uv run ruff check and uv run ruff format --check — all clean

🤖 Generated with Claude Code

Validate that the source file is within the configured module root before
making expensive AI API calls. If misconfigured, auto-correct by inferring
the module root from package.json fields and directory conventions (src/,
lib/, etc.), matching the existing Python validation pattern.

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

claude bot commented Mar 4, 2026

Claude finished @aseembits93's task in 8m 58s —— View job


PR Review Summary

  • Triage PR scope — substantive code changes, full review proceeding
  • Lint and typecheck — prek passed; fixed 2 mypy errors (committed)
  • Resolve stale review threads — no prior threads
  • Code review — complete
  • Duplicate detection — complete
  • Test coverage — 97% on validation util, 16/16 tests passing
  • Post summary
  • Check optimization PRs — closed 28 stale/CI-failing PRs

Prek Checks

Ruff check and format both pass. Two mypy errors were found in the new code and auto-fixed in commit cb1492f7:

  • codeflash/languages/javascript/function_optimizer.py:103 — wrong import: Language was imported from codeflash.languages.base (which re-exports it from language_enum); changed to from codeflash.languages.language_enum import Language directly.
  • function_optimizer.py:45,59,60,93self.args is typed Namespace | None but accessed without a null-guard. Added early-return guards (if self.args is None: return False / return super().can_be_optimized()) to both try_correct_module_root() and can_be_optimized(). This is also semantically correct behavior.

Code Review

Bug / Dead code — try_correct_module_root() lines 60–61:

self.args.project_root = project_root  # project_root = self.project_root — unchanged
self.project_root = project_root       # same: self.project_root = self.project_root

project_root is assigned from self.project_root on line 44 and never mutated, so these two lines are pure no-ops. Fix this →

Double validation — can_be_optimized() calls validate_js_module_resolution twice:
try_correct_module_root() calls validate_js_module_resolution internally (line 49) to decide whether correction is needed, then can_be_optimized() calls it again (line 100) to decide whether to return Failure. After try_correct_module_root() successfully corrects the root, the second call is fine (it will pass). But if the file is already valid, validate_js_module_resolution is called unnecessarily twice. Minor inefficiency, not a bug.

Side effect concern — auto-modifying package.json from can_be_optimized():
try_correct_module_root() silently writes the corrected moduleRoot back to package.json as a side effect of can_be_optimized(). The PR description says this is intentional ("auto-corrects … and writes the corrected value back"), but it's worth noting this is a visible-to-user behavior change (modifies a tracked file) triggered deep in an optimization pre-flight check. The Python equivalent (prepare_module) doesn't write to config files. Consider whether the user should be prompted or at least given a distinct log message (the current logger.info is fine but could be more prominent as a logger.warning).

Late import of PACKAGE_JSON_DATA_CACHE inside a function body:

from codeflash.code_utils.config_js import PACKAGE_JSON_DATA_CACHE
PACKAGE_JSON_DATA_CACHE.pop(package_json_path, None)

This import is inside a try block inside try_correct_module_root(). It should be moved to the top of the file with other imports. Fix this →

Duplicate Detection

MEDIUM confidenceinfer_js_module_root() in config_js_validation.py is a thin wrapper around detect_module_root() from config_js.py, which itself has nearly identical logic to _detect_js_module_root() in setup/detector.py. This is a pre-existing duplication between config_js.py and setup/detector.py — the new code correctly delegates to the existing detect_module_root() utility rather than reimplementing it, so no new duplication is introduced by this PR.

No other duplicates detected.

Test Coverage

File Coverage
codeflash/code_utils/config_js_validation.py 97% (35 stmts, 1 miss)
codeflash/languages/javascript/function_optimizer.py 43% (pre-existing code accounts for most uncovered lines)

The one uncovered line is config_js_validation.py:79 — the branch where get_package_json_data() returns None (malformed package.json). Minor gap; consider adding a test with an empty/invalid package.json.

All 16 new tests pass.


Last updated: 2026-03-04T03:22Z

- Add null guards for self.args in try_correct_module_root() and can_be_optimized()
- Fix Language import to use codeflash.languages.language_enum

Co-authored-by: Aseem Saxena <undefined@users.noreply.github.com>
from pathlib import Path


def validate_js_module_resolution(source_file: Path, project_root: Path, module_root: Path) -> tuple[bool, str]:
Copy link
Contributor

Choose a reason for hiding this comment

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

Best to place and dedupe with logic present in file 'init_javascript.py'

return True, ""


def infer_js_module_root(source_file: Path, project_root: Path | None = None) -> Path:
Copy link
Contributor

Choose a reason for hiding this comment

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

There are functions for this purpose we can strength the logic there.
collect_js_setup_info

Copy link
Contributor

Choose a reason for hiding this comment

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

or look into detect_module_root in config_js.py

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.

2 participants