Skip to content

fix(create-app): Fix critical CLI validation bugs and improve error handling#34472

Open
fmontes wants to merge 24 commits intomainfrom
issue-create-app-cli-critical-bugs
Open

fix(create-app): Fix critical CLI validation bugs and improve error handling#34472
fmontes wants to merge 24 commits intomainfrom
issue-create-app-cli-critical-bugs

Conversation

@fmontes
Copy link
Member

@fmontes fmontes commented Feb 1, 2026

Summary

Fixes critical bugs and adds robust validation to the @dotcms/create-app CLI tool. This PR addresses multiple issues including nested directory creation, path display problems, exit code inconsistencies, authentication failures, and improves overall error handling with comprehensive pre-flight checks.


Key Improvements & Bug Fixes

🐛 Critical Bug Fixes

1. Nested Directory Structure (NEW)

Issue: Running CLI with directory path that includes project name created nested structure

# Before
dotcms-create-app my-app -d /tmp/my-app
# Created: /tmp/my-app/my-app ❌

# After  
# Creates: /tmp/my-app ✅

Fix: Detect when directory path already ends with project name and avoid double-nesting

2. Directory Path Display (NEW)

Issue: Confusing output with excessive parent directory traversals

# Before
cd ../../../../tmp/test-dir/my-project

# After
cd /tmp/test-dir/my-project  # Cleaner absolute path

Fix: Smart path display logic - uses absolute paths when relative would have 3+ parent traversals

3. Exit Code Consistency (NEW)

Issue: CLI exited with code 0 on failures, breaking CI/CD detection

# 14+ failure scenarios were exiting with code 0

Fix: All error paths now use process.exit(1) for proper failure signaling

4. Authentication Error Handling (NEW)

Issue: Cryptic JSON dumps on wrong credentials, no retry mechanism

# Before: JSON error dump
# After: Clear message with 3-attempt retry

Fix:

  • User-friendly error messages distinguishing 401 vs connection vs server errors
  • 3-attempt retry loop for authentication failures
  • Users can correct credentials without restarting CLI

5. URL Trailing Slash Issues (NEW)

Issue: URLs with trailing slashes caused double-slash API endpoints

https://demo.dotcms.com/ + /api/v1/... → https://demo.dotcms.com//api/v1/...

Fix: Normalize URLs by stripping trailing slashes before API calls

🐳 Docker & Port Pre-Flight Checks

Before: Generic error

✖ Failed to start dotCMS ensure docker is running and ports 8082, 8443, 9200, and 9600 are free.

After: Specific errors with solutions

  • ✅ Check Docker availability → Installation instructions + download link
  • ✅ Check port conflicts → Lists busy ports with platform-specific diagnostic commands (lsof / netstat)
  • ✅ Container diagnostics → Shows status and logs when startup fails

🛡️ Input Validation

  • Project names: Stricter validation - only alphanumeric, hyphens, underscores, dots (no path traversal, reserved names)
  • Frameworks: Supports aliases (nextnextjs) and case-insensitive matching
  • URLs: Protocol requirement (https:// or http://), trailing slash normalization
  • Usernames/Passwords: Non-empty field validation
  • Parameters: Warns when mixing --local with cloud flags (--url, -u, -p)

🔧 Error Handling & Code Quality

  • Added health check retry constants (Cloud: 5 attempts, Local: 60 attempts)
  • Better variable naming (healthCheckResult vs checkIfDotcmsIsRunning)
  • Changed console.logconsole.error for error outputs (proper stream)
  • Fixed typos throughout codebase
  • Added comprehensive JSDoc comments
  • Modular utility organization (getDockerDiagnostics() moved to utils)

🔒 Security

  • Path traversal prevention in project names
  • Shell injection protection with escapeShellPath() utility
  • URL protocol validation (prevents file:// or javascript: schemes)
  • Cross-platform command escaping (Windows/macOS/Linux)

Detailed Changes by Category

Authentication & Network (4 commits)

  • ✅ Enhanced getAuthToken() API error handling
  • ✅ 3-attempt authentication retry with user prompts
  • ✅ URL trailing slash normalization
  • ✅ Distinguish 401 vs connection vs 500 errors

Validation (2 commits)

  • ✅ Stricter project name validation (alphanumeric + -_. only)
  • ✅ URL validation with protocol requirement
  • ✅ Empty field validation for credentials
  • ✅ Conflicting parameter detection

Directory Handling (2 commits)

  • ✅ Prevent nested directory structures
  • ✅ Smart relative/absolute path display

Infrastructure (3 commits)

  • ✅ Docker availability checks with actionable errors
  • ✅ Port conflict detection (8082, 8443, 9200, 9600)
  • ✅ Container diagnostic utilities
  • ✅ Exit code consistency (process.exit(1) on all failures)

Files Changed

File Changes Description
src/index.ts +60/-30 Main CLI flow, authentication retry, path display
src/utils/index.ts +140/-10 Docker checks, port validation, path helpers
src/utils/validation.ts +318 (new) Comprehensive input validation
src/asks.ts +30/-10 Directory preparation, nested structure fix
src/api/index.ts +20/-5 Enhanced error handling
src/constants/index.ts +5 Health check retry constants

Total: ~500 lines added/modified across 7 commits


Testing

✅ Build passing (nx run sdk-create-app:build)
✅ Lint passing (nx run sdk-create-app:lint)
✅ All pre-commit hooks passing
✅ Manually tested: Docker checks, port conflicts, auth retries, path display, nested directories

Test Scenarios Validated

  • ✅ Wrong credentials → retry 3 times with friendly messages
  • ✅ Docker not running → clear installation instructions
  • ✅ Ports busy → lists conflicts with diagnostic commands
  • ✅ Directory path includes project name → no nesting
  • ✅ Deep relative paths → shows absolute when cleaner
  • ✅ All failures → exit with code 1 (not 0)
  • ✅ URL trailing slashes → normalized correctly
  • ✅ Invalid project names → clear validation errors

Breaking Changes

None - all changes are additive and backward compatible.


Related Issues

Fixes multiple critical bugs discovered during QA testing of @dotcms/create-app CLI tool.

fmontes and others added 3 commits January 29, 2026 18:06
…andling

This commit addresses 4 critical bugs identified during QA testing:

1. **Late Framework Validation** - Framework validation now occurs immediately
   after the welcome screen, before any API calls or interactive prompts. Invalid
   frameworks fail fast with clear error messages.

2. **Invalid URL Retry Loop** - Added comprehensive URL format validation that
   catches malformed URLs before connection attempts. URLs must now include
   protocol (http:// or https://), preventing infinite retry loops.

3. **Framework Case Sensitivity** - Framework names are now case-insensitive.
   Users can enter NextJS, nextjs, NEXTJS, etc.

4. **Positional Arguments** - Verified working correctly (was already implemented).

Additional improvements:
- Added framework aliases (next → nextjs, ng → angular, next.js → nextjs)
- Enhanced fetchWithRetry() to track error history and provide troubleshooting steps
- Increased Docker startup timeout from 40 to 60 retries (5 minutes) for first-time pulls
- Fixed typo in prompt: "exsisting" → "existing"
- Added localhost port warning when using non-standard ports
- Updated README with framework aliases and URL format requirements
- All error messages styled with chalk colors and emojis for consistency

Files changed:
- NEW: src/utils/validation.ts - Centralized validation logic
- MODIFIED: src/index.ts - Early validation calls, updated retry parameters
- MODIFIED: src/utils/index.ts - Enhanced error handling in fetchWithRetry()
- MODIFIED: src/asks.ts - Fixed typo
- MODIFIED: README.md - Updated documentation

All changes are backward compatible. The CLI is now more permissive (accepts
more input variations) while providing clearer error messages for invalid input.

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
This commit introduces several improvements to the CLI validation process:

1. **New Validation Functions**: Added  to ensure project names are filesystem-safe and follow best practices, and  to warn users about conflicting CLI options.

2. **Updated Validation Calls**: Integrated new validation functions into the CLI flow, ensuring immediate feedback on project name and parameter conflicts.

3. **Path Escaping**: Implemented  to safely handle file paths in shell commands, enhancing cross-platform compatibility.

These changes improve user experience by providing clearer error messages and preventing invalid configurations.

Files changed:
- MODIFIED: src/index.ts - Added new validation calls
- MODIFIED: src/utils/index.ts - Updated project path handling
- NEW: src/utils/validation.ts - Introduced new validation logic

All changes maintain backward compatibility and enhance the robustness of the CLI.
Address code review feedback to enhance security, maintainability, and user experience:

**Validation Improvements:**
- Add post-prompt validation to prevent bypass of interactive project name input
- Implement platform-specific shell escaping (Windows vs Unix backslash handling)
- Add newline and tab character detection in shell path escaping

**Code Quality:**
- Extract magic number 255 to MAX_PROJECT_NAME_LENGTH constant
- Add CONTROL_CHAR_THRESHOLD constant for ASCII validation
- Replace console.log with console.warn for warning messages
- Add explanatory comments for ESLint fixes and regex patterns

**Error Handling:**
- Wrap main action in try-catch for consistent error handling
- Graceful exit with proper error messages on validation failures
- Improved user feedback for all error scenarios

**Security:**
- Close validation bypass vulnerability in interactive mode
- Enhanced cross-platform shell injection protection
- Better handling of edge cases (tabs, newlines, Windows paths)

All changes maintain backward compatibility and pass ESLint validation.

Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
The CLI was experiencing repeated HTTP 403 errors when checking if dotCMS
was ready during startup, even though containers were running healthy.

Root Cause:
- The /api/v1/probes/alive endpoint has IP-based access control
- Requests from Docker host appear as coming from Docker gateway IP
- MonitorHelper ACL blocks these requests despite gateway IP being in
  allowed private network range (172.16.0.0/12)

Solution:
- Changed health check endpoint from /api/v1/probes/alive to
  /api/v1/appconfiguration
- New endpoint has no ACL restrictions and reliably indicates when
  dotCMS REST API is ready
- Works transparently for users with no configuration needed

Additional Improvements:
- Enhanced error messages with better categorization (Connection Refused,
  Timeout, HTTP errors)
- Added Docker container diagnostics on failure showing:
  - Container status and health
  - Recent logs from problematic containers
  - Specific troubleshooting steps
- Better retry feedback showing specific error types

Tracking: #34509

The core dotCMS ACL issue will be addressed separately in the backend,
but this CLI fix provides immediate resolution for users.
- Add DEBUG mode support to preserve stack traces for debugging
- Handle non-Error exceptions properly in error handler
- Add explicit empty string check in URL validation
- Fix typos in user-facing messages: successfully, authentication, retrieved

These changes improve debuggability while maintaining clean user experience.
- Add Docker availability check before attempting to start containers
- Add port availability check for required ports (8082, 8443, 9200, 9600)
- Split generic error into specific, actionable error messages
- Show which specific ports are busy with platform-specific diagnostic commands
- Provide clear installation/troubleshooting steps for each error scenario
- Add progress spinners for each validation step

This improves user experience by immediately identifying the root cause
(Docker not installed/running vs ports already in use) and providing
targeted solutions instead of a generic error message.
- Add health check constants (CLOUD_HEALTH_CHECK_RETRIES, LOCAL_HEALTH_CHECK_RETRIES)
- Rename 'checkIfDotcmsIsRunning' to 'healthCheckResult' for clarity
- Remove duplicate projectName validation (only validate interactive prompt)
- Use console.error for error outputs instead of console.log
- Explicitly specify retry counts for both cloud and local health checks

These changes improve code maintainability, type clarity, and consistency
throughout the error handling flow.
…atures

- Document Docker pre-flight checks (availability, ports)
- Add comprehensive troubleshooting section
- Document DEBUG mode for stack traces
- Add security notes about input validation
- Include examples for different usage patterns
- Document all validation features (project names, URLs, frameworks)
- Add platform-specific troubleshooting commands
- Improve formatting and clarity throughout
- Remove duplicate 'docker info' check from getDockerDiagnostics
- Reuse checkDockerAvailability() function instead
- Reduces code duplication and provides consistent error messages
- No functional changes, just DRYer code

This fixes the duplication between checkDockerAvailability (utils) and
getDockerDiagnostics (index) that both checked Docker availability.
- Move getDockerDiagnostics from index.ts to utils/index.ts
- Co-locate with other Docker utility functions (checkDockerAvailability, checkPortsAvailability)
- Better code organization and separation of concerns
- Main CLI file (index.ts) now focuses on orchestration, not implementation

This groups all Docker-related utilities together in one place.
@fmontes fmontes requested review from a team, AP2300, AfaqJaved, KevinDavilaDotCMS, Copilot and hmoreras and removed request for a team February 5, 2026 03:26
Copy link
Contributor

Copilot AI left a comment

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 enhances the @dotcms/create-app CLI tool with comprehensive validation, improved error handling, and Docker environment pre-flight checks. The changes transform generic error messages into specific, actionable feedback with clear solutions for common issues.

Changes:

  • Added new validation module with input sanitization for project names, URLs, frameworks, and parameters
  • Implemented Docker pre-flight checks (availability and port conflicts) with detailed diagnostics
  • Enhanced error messages with DEBUG mode support and platform-specific troubleshooting commands
  • Refactored health check logic to use different retry counts for cloud vs. local instances
  • Updated health check endpoint from /api/v1/probes/alive to /api/v1/appconfiguration due to IP ACL restrictions

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
src/utils/validation.ts New validation module with project name, URL, framework, and parameter validation functions
src/utils/index.ts Added Docker availability check, port availability check, and diagnostic utilities; enhanced fetchWithRetry with better error tracking
src/index.ts Integrated validation at CLI entry point, added try-catch error handling, split cloud/local flows with appropriate retry counts
src/constants/index.ts Added retry count constants for cloud vs. local deployments and updated health check endpoint
src/asks.ts Fixed typo: "exsisting" → "existing"
README.md Comprehensive documentation updates covering validation features, error handling, troubleshooting, and examples

Copy link
Contributor

Copilot AI commented Feb 5, 2026

@fmontes I've opened a new pull request, #34513, to work on those changes. Once the pull request is ready, I'll request review from you.

fmontes and others added 7 commits February 5, 2026 07:07
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
… validation logic

- Refactor project name handling to ensure consistent validation regardless of input source (CLI or interactive prompt).
- Update URL validation to separate parsing errors from protocol and hostname checks, providing clearer error messages.
- Improve error handling in fetchWithRetry function to include detailed timeout information and connection issues.

These changes enhance the robustness of input validation and improve user feedback during the application setup process.
- Add empty field validation for username and password prompts
- Implement 3-attempt retry loop for authentication failures
- Replace cryptic error dumps with user-friendly messages
- Distinguish between 401 (auth failed), connection errors, and server errors
- Provide specific, actionable guidance for each error type

Before: Users could submit empty passwords and get confusing JSON error dumps
After: Input validated at prompt, clear error messages, and retry on auth failure

Fixes:
- Empty password/username submission blocked at prompt level
- 401 errors show 'Invalid username or password' with retry option
- Connection errors show URL and connectivity troubleshooting steps
- Users get 3 attempts to correct credentials without restarting CLI
fmontes and others added 6 commits February 5, 2026 10:12
…lashes

- Add normalizeUrl() function to remove trailing slashes
- Apply normalization after validation but before using URL
- Prevents double slashes in API endpoints (e.g., //api/v1/...)

Before: 'https://demo.dotcms.com/' → 'https://demo.dotcms.com//api/v1/...' (404)
After: 'https://demo.dotcms.com/' → 'https://demo.dotcms.com/api/v1/...' (works)

This fixes connection failures when users include trailing slashes in URLs.
- Only allow alphanumeric characters, hyphens, underscores, and dots
- Block names starting with hyphens (looks like command flags)
- Warn about names starting with dots (hidden directories)
- Prevent special characters that cause issues with npm, Docker, and other tools

Before: test@#$%project, 'my project', project! were accepted
After: Only safe characters allowed (a-zA-Z0-9._-)

This prevents compatibility issues with:
- npm package names
- Docker container names
- File system operations across platforms
- Command-line tools

Includes helpful error messages with valid/invalid examples.
- Replace all error 'return;' statements with 'process.exit(1)'
- Ensure successful completion exits with code 0 (default)
- Fixed 14+ failure scenarios that were exiting with code 0

Before: Failures like max auth attempts, connection errors, Docker failures
        exited with code 0, making them undetectable by CI/CD and scripts
After: All failures exit with code 1, successes exit with code 0

This enables proper error detection in:
- CI/CD pipelines
- Shell scripts checking $?
- Automation tools
- Process monitoring systems

Affected scenarios:
- Health check failures
- Authentication failures (including max retry)
- Docker/port availability issues
- Container startup failures
- Dependency installation failures
- Add getDisplayPath() helper to choose between relative and absolute paths
- Use absolute paths when relative paths would have 3+ parent traversals
- Prevents confusing output like 'cd ../../../../tmp/test-dir'
- Now shows cleaner paths like 'cd /tmp/test-dir' when appropriate
…s project name

- Detect if directory path already ends with project name
- Avoid creating nested structure like /tmp/my-app/my-app
- Works for both -d flag and interactive directory input
- Example: -d /tmp/my-app with projectName=my-app now creates /tmp/my-app (not /tmp/my-app/my-app)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

6 participants