iOfficeAI/OfficeCLI · warning · InvalidOperationException

app_not_authentic: {name}

Error message

app_not_authentic: {name}

What it means

Thrown inside PowerPointPngBackend.RenderGridCore when CoCreateInstance for PowerPoint's CLSID (91493441-5A91-11CF-8700-00AA0060263B) returns an IDispatch whose Name property does not contain 'PowerPoint'. This is a COM-authenticity guard: it detects when a different application (or a stub/viewer) is registered under PowerPoint's CLSID. The exception is caught internally by RenderGrid's STA thread and results in a null return, causing the caller to fall back to HTML screenshot rendering — the user never sees this error text directly.

Source

Thrown at src/officecli/Core/PowerPointPngBackend.cs:86

        });
        th.SetApartmentState(ApartmentState.STA);
        th.IsBackground = true;
        th.Start();
        if (!th.Join(timeoutMs + 30000)) return null;
        if (error != null) return null;
        return result;
    }

    static byte[]? RenderGridCore(string pptx, int startSlide, int endSlide, int cellW, int cellH, int cols, int gap, int pad, int timeoutMs, List<string> tmp)
    {
        if (cols < 1) cols = 1;
        var clsid = G_App; var iid = WordPdfBackend.G_IDispatch;
        WordPdfBackend.CoCreateInstance(ref clsid, IntPtr.Zero, 4, ref iid, out var app);
        try
        {
            var name = (string?)WordPdfBackend.DispGet(app, "Name") ?? "";
            if (!name.Contains("PowerPoint", StringComparison.OrdinalIgnoreCase))
                throw new InvalidOperationException("app_not_authentic: " + name);
            try { WordPdfBackend.DispSet(app, "DisplayAlerts", 1); } catch { /* alerts-none; ignore if unsettable */ }

            var presentations = (IntPtr)WordPdfBackend.DispGet(app, "Presentations")!;
            try
            {
                var pres = (IntPtr)WordPdfBackend.DispMethod(presentations, "Open", Path.GetFullPath(pptx), -1, 0, 0)!;
                try
                {
                    var slides = (IntPtr)WordPdfBackend.DispGet(pres, "Slides")!;
                    try
                    {
                        var count = WaitForCount(slides, timeoutMs);
                        int s = Math.Max(1, startSlide);
                        int e = Math.Min(count, endSlide <= 0 ? count : endSlide);
                        if (e < s) return null;
                        int n = e - s + 1;
                        int rows = (n + cols - 1) / cols;

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Install full Microsoft PowerPoint (not just the Viewer) and verify it launches manually.
  2. Run Office Repair: Settings → Apps → Microsoft 365/Office → Modify → Online Repair, which re-registers COM classes.
  3. Check COM registration: run 'regedit' and verify HKCR\PowerPoint.Application\CLSID points to the correct server DLL/exe.
  4. Verify bitness: a 64-bit OfficeCLI needs a 64-bit PowerPoint COM server (or a working cross-bitness surrogate).
  5. Since this error is caught internally and triggers HTML fallback, rendering will still work — just slower and lower quality. If that's acceptable, no action is needed.
Defensive patterns

Strategy: fallback

Validate before calling

// Before rendering, verify PowerPoint COM is available
static bool IsPowerPointAvailable()
{
    try
    {
        var t = Type.GetTypeFromProgID("PowerPoint.Application");
        return t != null;
    }
    catch { return false; }
}

if (!IsPowerPointAvailable())
    Console.Error.WriteLine("PowerPoint COM not available — will fall back to HTML rendering.");

Try / catch

// This error is caught internally by PowerPointPngBackend — the caller
// already handles it via null return. No additional try-catch needed:
var png = PowerPointPngBackend.RenderGrid(pptx, start, end, ...);
if (png is null)
{
    // PowerPoint unavailable or app_not_authentic — fall back to HTML path.
    png = HtmlScreenshotRenderer.Render(pptx, start, end, ...);
}

Prevention

When it happens

Trigger: PowerPointPngBackend.RenderGrid(...) → RenderGridCore(...) calls CoCreateInstance(ref G_App, ...) then DispGet(app, "Name"). If the Name doesn't contain 'PowerPoint' (case-insensitive), the guard fires. This can happen when only PowerPoint Viewer is installed, when a different COM server hijacked the CLSID, or when a 32/64-bit mismatch resolves to a wrong surrogate.

Common situations: Machine has PowerPoint Viewer (not full PowerPoint) registered under the CLSID. COM registration is corrupted — a repair or reinstall is needed. 32-bit vs 64-bit COM surrogate mismatch on Windows. A third-party presentation tool registered itself under PowerPoint's CLSID. PowerPoint trial expired and fell back to a viewer shell.

Related errors


AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13). Data as JSON: /api/errors/4a967fa0f6fe1dc9. Report an issue: GitHub.