Skip to content

Bug: PSModuleInfo.Author returns empty string when called via PowerShell Runspace #1902

@GrexyLoco

Description

@GrexyLoco

🐛 Bug Description

Utils.ValidateModuleManifest() fails with false positive "No author was provided" error when called via [PowerShell]::Create() runspace, even though the module manifest contains a valid Author field.

The issue occurs because PSModuleInfo.Author property returns empty string when the object is deserialized across PowerShell runspace boundary.

📍 Affected Code

File: src/code/Utils.cs
Lines: 1388-1403

public static bool ValidateModuleManifest(string moduleManifestPath, out string errorMsg)
{
    using (System.Management.Automation.PowerShell pwsh = System.Management.Automation.PowerShell.Create())
    {
        results = pwsh.AddCommand("Test-ModuleManifest")
            .AddParameter("Path", moduleManifestPath)
            .Invoke();  // ← Line 1388: Runspace call
        
        if (pwsh.HadErrors)
        {
            if (results.Any())
            {
                PSModuleInfo psModuleInfoObj = results[0].BaseObject as PSModuleInfo;
                if (string.IsNullOrWhiteSpace(psModuleInfoObj.Author))  // ← Line 1403: BUG HERE!
                {
                    errorMsg = "No author was provided...";
                    return false;
                }

🔬 Root Cause

PSModuleInfo property deserialization fails when object crosses PowerShell runspace boundary.

Test Case 1: Direct Call (Works ✅)

$manifest = Test-ModuleManifest -Path "manifest.psd1"
$manifest.Author  # → 'GrexyLoco' ✅

Test Case 2: Runspace Call (Fails ❌)

$pwsh = [PowerShell]::Create()
$results = $pwsh.AddCommand("Test-ModuleManifest").AddParameter("Path", "manifest.psd1").Invoke()
$psModuleInfo = $results[0].BaseObject
$psModuleInfo.Author  # → '' (empty string) ❌
$pwsh.HadErrors       # → False
$pwsh.Dispose()

Comparison Table:

Method Call Type Author Value pwsh.HadErrors Result
Direct Test-ModuleManifest -Path 'GrexyLoco' N/A ✅ Works
Runspace [PowerShell]::Create() '' (empty) False ❌ Fails

💥 Impact

Symptom: Publish-PSResource throws error:

No author was provided in the module manifest

Workaround Required:

Publish-PSResource -Path ./Module -Repository MyRepo -SkipModuleManifestValidate

This forces users to bypass validation entirely, which is not ideal for catching actual manifest issues.

🔧 Suggested Fix

Option 1: Use direct Test-ModuleManifest call (preferred)

// Instead of runspace, use direct cmdlet invocation
var manifestValidation = InvokeCommand.InvokeScript(
    $"Test-ModuleManifest -Path '{moduleManifestPath}'"
).FirstOrDefault()?.BaseObject as PSModuleInfo;

Option 2: Serialize specific properties explicitly

// Request explicit property serialization before crossing runspace boundary
pwsh.AddCommand("Test-ModuleManifest")
    .AddParameter("Path", moduleManifestPath);
    
var results = pwsh.Invoke();
var moduleInfo = results[0];

// Access properties via PSObject instead of BaseObject
string author = moduleInfo.Properties["Author"]?.Value?.ToString();

Option 3: Add null/empty check with better error message

if (string.IsNullOrWhiteSpace(psModuleInfoObj.Author))
{
    // Re-validate with direct call to confirm
    var directTest = InvokeCommand.InvokeScript(
        $"(Test-ModuleManifest -Path '{moduleManifestPath}').Author"
    ).FirstOrDefault()?.ToString();
    
    if (!string.IsNullOrWhiteSpace(directTest))
    {
        // Runspace deserialization bug - use direct result
        psModuleInfoObj.Author = directTest;
    }
    else
    {
        errorMsg = "No author was provided...";
        return false;
    }
}

🧪 Reproduction Steps

  1. Create valid module manifest with Author = 'TestAuthor'
  2. Call Publish-PSResource -Path ./Module -Repository MyRepo
  3. Observe error: "No author was provided in the module manifest"
  4. Verify manifest with direct Test-ModuleManifest → works correctly

📋 Environment

  • PSResourceGet Version: 1.1.1 (stable), 1.2.0-preview3
  • PowerShell Version: 7.4.6
  • OS: Windows 11, GitHub Actions (Ubuntu/Windows runners)
  • Manifest File: Valid .psd1 with all required fields including Author

📎 References

✅ Expected Behavior

ValidateModuleManifest() should correctly read Author property from module manifest regardless of execution context (direct vs runspace).

❌ Actual Behavior

Author property returns empty string when PSModuleInfo object is returned from [PowerShell]::Create() runspace, causing false positive validation failure.


This bug forces users to disable manifest validation entirely via -SkipModuleManifestValidate, which defeats the purpose of the validation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions