stablyai/orca · error

PowerShell returned malformed signature JSON: ${error.messag

Error message

PowerShell returned malformed signature JSON: ${error.message}

What it means

Thrown by parseSignatureJson() when PowerShell returns non-empty stdout but JSON.parse() fails on it. The original JSON.parse error message is appended. This indicates PowerShell produced output, but it is not valid JSON — partial output, interleaved text, or an encoding issue.

Source

Thrown at config/scripts/verify-windows-inner-signature.mjs:72

    return []
  }

  return value
    .split(/[\r\n,;]+/u)
    .map(normalizeThumbprint)
    .filter(Boolean)
}

export function parseSignatureJson(stdout) {
  const trimmed = typeof stdout === 'string' ? stdout.trim() : ''
  if (trimmed === '') {
    throw new Error('PowerShell did not return signature JSON.')
  }

  try {
    return JSON.parse(trimmed)
  } catch (error) {
    throw new Error(`PowerShell returned malformed signature JSON: ${error.message}`)
  }
}

export function classifySignature(signature, options = {}) {
  const expectedSigners = options.expectedSigners ?? parseExpectedSigners()
  const expectedThumbprints = options.expectedThumbprints ?? parseExpectedThumbprints()
  const status = typeof signature?.status === 'string' ? signature.status : ''
  const signerSubject = normalizeSignerSubject(signature?.signerSubject)
  const signerThumbprint = normalizeThumbprint(signature?.signerThumbprint)
  const subjectAllowed = expectedSigners.includes(signerSubject)
  const thumbprintAllowed =
    expectedThumbprints.length > 0 &&
    signerThumbprint !== '' &&
    expectedThumbprints.includes(signerThumbprint)

  if (status !== 'Valid') {
    return {
      ok: false,

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Capture the raw stdout (the error message includes it) and inspect what precedes or breaks the JSON structure.
  2. If the issue is ConvertTo-Json depth, add -Depth 10 to the ConvertTo-Json call in POWERSHELL_SIGNATURE_SCRIPT.
  3. If extra text leaks into stdout, ensure -NoProfile is effective and no module auto-load writes to stdout; consider piping through Out-String or using $PSStyle to disable progress.
  4. Set [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 in the script to avoid encoding issues.

Example fix

// before: depth-limited JSON truncates nested cert data
} | ConvertTo-Json -Compress

// after: explicit depth + UTF-8 output encoding
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
} | ConvertTo-Json -Compress -Depth 10
Defensive patterns

Strategy: try-catch

Validate before calling

function preflightJsonOutput(executablePath) {
  const result = spawnSync('pwsh', ['-NoProfile', '-Command',
    '[pscustomobject]@{ ok = $true } | ConvertTo-Json -Compress -Depth 10'],
    { encoding: 'utf8' }
  )
  try {
    JSON.parse(result.stdout)
  } catch {
    throw new Error('PowerShell cannot produce valid JSON — check encoding/profile settings')
  }
}

Type guard

function isParsableJson(value) {
  if (typeof value !== 'string' || value.trim() === '') return false
  try { JSON.parse(value); return true } catch { return false }
}

Try / catch

try {
  return parseSignatureJson(stdout)
} catch (err) {
  if (err.message.includes('malformed signature JSON')) {
    // Attempt to extract JSON from mixed output
    const match = stdout.match(/\{[\s\S]*\}/u)
    if (match) {
      return JSON.parse(match[0])
    }
  }
  throw err
}

Prevention

When it happens

Trigger: getPowerShellSignatureJson() returns stdout that trim()s to a non-empty string but JSON.parse throws. Caused by: PowerShell writing a progress message or banner to stdout before the JSON; ConvertTo-Json truncating due to depth limits; BOM or encoding artifacts breaking the parse; the script hitting an error that writes a partial object.

Common situations: A PowerShell profile or module auto-load injecting text into stdout (the script uses -NoProfile to prevent this, but module auto-loading can still occur); ConvertTo-Json depth default (2) being too shallow for nested certificate objects; UTF-16 BOM from PowerShell output encoding; a Windows update changing Get-AuthenticodeSignature output shape.

Understand the failure class

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/79cc3c5e26aff1e0. Report an issue: GitHub.