Skip to content

[META] Initialization System Overhaul - Fix Startup Failures #8

Description

@SevWren

Overview

This meta-issue tracks the complete fix for the initialization system failures that prevent the application from launching. Multiple related bugs create a cascading failure where the app cannot create its required directory structure.

Current State: BROKEN

App fails to launch with these errors:

  1. "The property 'Path' cannot be found on this object"
  2. "Cannot bind argument to parameter 'Path' because it is null"
  3. "Required modules failed to load. The variable '$modulesDir' cannot be retrieved because it has not been set."

Root cause: %APPDATA%\DailyMotivationBrainHelper\ directory is never created, and there's no fallback.

Related Issues (Implementation Order)

Phase 1: Critical Path Fixes

These must be fixed first for the app to launch at all:

  1. CRITICAL: Initialize-AppData not creating %APPDATA% directory structure #2 - Initialize-AppData not creating directory structure ⚠️ CRITICAL

    • Initialize-AppData function not working
    • Must fix before anything else works
  2. BUG: $PSScriptRoot resolution fails in PS2EXE compiled executable #3 - $PSScriptRoot resolution in PS2EXE ⚠️ CRITICAL

    • Module paths don't resolve in compiled EXE
    • Blocks module imports
  3. BUG: Module import happens before Initialize-AppData, causing initialization failure #4 - Module import before Initialize-AppData ⚠️ CRITICAL

    • Wrong order of operations
    • Creates chicken-and-egg problem

Phase 2: Robustness Fixes

These prevent edge cases and improve error handling:

  1. BUG: DailyMotivation.ps1 doesn't call Initialize-AppData, assumes MainApp already ran #5 - DailyMotivation.ps1 doesn't call Initialize-AppData

    • Popup assumes MainApp already ran
    • Breaks if Task Scheduler fires first
  2. BUG: Silent exit behavior masks real initialization problems #6 - Silent exit masks initialization problems

    • No user feedback when things go wrong
    • Makes debugging impossible
  3. BUG: %TEMP% fallback in ConfigManager not used consistently across scripts #7 - %TEMP% fallback not used consistently

    • Fallback exists but doesn't work
    • Scripts still hardcode %APPDATA%

Implementation Plan

Step 1: Fix $PSScriptRoot Resolution (#3)

Goal: Reliable path resolution in both .ps1 and .exe modes

# MainApp.ps1 and DailyMotivation.ps1
$scriptDir = if ($PSScriptRoot -and $PSScriptRoot.Length -gt 0) {
    $PSScriptRoot
} elseif ($MyInvocation.MyCommand.Path) {
    Split-Path -Parent $MyInvocation.MyCommand.Path
} else {
    # PS2EXE fallback: use current directory
    $PWD.Path
}

# Validate it worked
if (-not (Test-Path $scriptDir)) {
    Show-ErrorDialog "Cannot determine installation directory. Please reinstall."
    exit 1
}

Test: Build EXE, run from Task Scheduler, verify paths resolve.

Step 2: Fix Initialization Order (#4)

Goal: Initialize-AppData runs before module imports

# MainApp.ps1 - NEW ORDER:
# 1. Resolve script directory (no modules needed)
$scriptDir = ...

# 2. Create APPDATA directory INLINE (before modules)
$appDataDir = Join-Path $env:APPDATA "DailyMotivationBrainHelper"
if (-not (Test-Path $appDataDir)) {
    try {
        New-Item -ItemType Directory -Path $appDataDir -Force | Out-Null
    } catch {
        Show-ErrorDialog "Cannot create app data directory: $appDataDir`n`n$_"
        exit 1
    }
}

# 3. NOW import modules
$modulesDir = Join-Path $scriptDir "Modules"
Import-Module (Join-Path $modulesDir "ConfigManager.psm1") -Force -ErrorAction Stop
Import-Module (Join-Path $modulesDir "TaskScheduler.psm1") -Force -ErrorAction Stop

# 4. Call full Initialize-AppData to create config files
Initialize-AppData

Test: Delete %APPDATA%\DailyMotivationBrainHelper, launch app, verify directory created before module load.

Step 3: Fix Initialize-AppData (#2)

Goal: Robust directory and file creation

function Initialize-AppData {
    # Directory already created by MainApp inline code above
    # This function now just creates FILES
    
    # app_settings.json
    if (-not (Test-Path $script:SettingsPath)) {
        try {
            @{
                firstRun = $true
                lastFolder = ""
                recentFolders = @()
                theme = "dark"
            } | ConvertTo-Json -Depth 3 | Set-Content -Path $script:SettingsPath -Encoding UTF8 -ErrorAction Stop
        } catch {
            throw "Failed to create app_settings.json: $_"
        }
    }
    
    # tasks.json
    if (-not (Test-Path $script:TasksPath)) {
        try {
            "[]" | Set-Content -Path $script:TasksPath -Encoding UTF8 -ErrorAction Stop
        } catch {
            throw "Failed to create tasks.json: $_"
        }
    }
    
    # popup_config.json
    if (-not (Test-Path $script:ConfigPath)) {
        try {
            @{
                glyph = "[+]"
                title = ""
                body = ""
                explorer_path = ""
                folder_name = ""
                task_id = ""
            } | ConvertTo-Json | Set-Content -Path $script:ConfigPath -Encoding UTF8 -ErrorAction Stop
        } catch {
            throw "Failed to create popup_config.json: $_"
        }
    }
    
    # REMOVE fallback to %TEMP% - if we got here, %APPDATA% works
}

Test: Delete each file individually, run app, verify recreated with correct content.

Step 4: Fix DailyMotivation.ps1 Initialization (#5)

Goal: Popup script is self-sufficient

# DailyMotivation.ps1
$script:ModulesPath = Join-Path $PSScriptRoot "Modules"

# Import module
Import-Module (Join-Path $script:ModulesPath "ConfigManager.psm1") -Force -ErrorAction Stop

# Ensure directory exists (DailyMotivation.ps1 must work standalone)
Initialize-AppData

# Load config
$configPath = Join-Path $env:APPDATA "DailyMotivationBrainHelper\popup_config.json"
if (-not (Test-Path $configPath)) {
    Show-ErrorDialog "Configuration file not found. Please run the Daily Motivation Brain Helper application to schedule a folder."
    exit 1
}

$config = Get-Content $configPath -Raw -Encoding UTF8 | ConvertFrom-Json
if (-not $config -or -not $config.explorer_path -or $config.explorer_path -eq "") {
    # Only NOW is silent exit acceptable
    Write-DLog "No folder configured yet" "INFO"
    exit 0
}

Test: Delete %APPDATA%\DailyMotivationBrainHelper, trigger Task Scheduler, verify graceful error.

Step 5: Fix Error Handling (#6)

Goal: Clear error messages, no silent failures

  • Remove silent exit for missing config file
  • Add error dialogs with actionable messages
  • Distinguish "not configured" from "broken"
  • Add debug logging at every decision point

Test: Trigger each failure mode, verify user gets helpful error dialog.

Step 6: Remove or Fix Fallback (#7)

Recommendation: Remove %TEMP% fallback

  • If %APPDATA% unavailable, show error and exit
  • Don't maintain complex fallback that doesn't work end-to-end
  • Document that app requires %APPDATA% access

Test: Block %APPDATA% creation (permissions), verify clear error message.

Success Criteria

  • Fresh install (no %APPDATA% directory) launches successfully
  • Compiled EXE works identically to .ps1
  • Task Scheduler launch works even if MainApp never ran
  • All error cases show clear, actionable error dialogs
  • No silent exits except for the legitimate "task not configured yet" case
  • Debug logs explain every decision

Testing Checklist

  • Delete %APPDATA%\DailyMotivationBrainHelper, launch MainApp.ps1, verify success
  • Delete %APPDATA%\DailyMotivationBrainHelper, build EXE, launch, verify success
  • Delete popup_config.json, trigger Task Scheduler, verify helpful error
  • Set %APPDATA% to invalid path, launch app, verify clear error
  • Run DailyMotivation.ps1 directly before MainApp, verify helpful error
  • Launch from Task Scheduler with current directory = C:\Windows\System32

Documentation Updates

  • Update INSTALL.md with prerequisites (%APPDATA% access required)
  • Update docs/FORENSIC_REVIEW.md with lessons from this bug
  • Update CLAUDE.md Critical Gotchas section
  • Add troubleshooting section to README.md

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions