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

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions