---
title: "Errors — Angular"
description: "What each numbered error from the Angular package means, and how to fix it."
framework: "Angular"
source: "https://www.embedpdf.com/docs/headless/angular/errors"
---

# Errors

When the viewer is set up in a way that can't work, the Angular package throws an error with a
number, such as `EPDF-101`, says how to fix it, and links here. Each section below is one number:
what happened, and the fix.

A document that isn't open yet, or a permission the user doesn't have, isn't a setup mistake: a
plugin refuses those with a `PluginError` (`not-ready`, `permission-denied`), the same in every
framework. See [Permissions](concepts/permissions).

## EPDF-101

**No viewer above it.** A service of the viewer (`inject(EpdfDocuments)`, `inject(EpdfViewer)`)
or one of its components (`<epdf-stage>`, `*epdfDocumentGate`) found no `provideEmbedPdf()` in
the component that uses it or in any component above it.

Add `provideEmbedPdf()` to the `providers` of the component that shows the viewer. That component
and everything in its template share the viewer, and the component can inject it itself:

**`provide-viewer.ts`**

```typescript
import { Component, inject } from '@angular/core';
import { EpdfDocuments, provideEmbedPdf } from '@embedpdf/angular/runtime';
import { withRender } from '@embedpdf/angular/render';
import { withStage } from '@embedpdf/angular/stage';
import { DownloadButton } from './download-button';
import { engine } from './pdf';

@Component({
  selector: 'app-document-viewer',
  imports: [DownloadButton],
  // The viewer, for this component and everything in its template
  providers: [provideEmbedPdf({ engine }, withStage(), withRender())],
  template: `<app-download-button />`,
})
export class DocumentViewer {
  // This component can inject it too
  private readonly documents = inject(EpdfDocuments);
}
```

For one viewer in the whole app, put the same call in `app.config.ts`; for one per route, in the
route's `providers`. A component outside the one that provides the viewer, such as a sibling in
your layout, can't reach it: move `provideEmbedPdf()` up to a component both are inside.

## EPDF-102

**No viewer with this plugin.** A plugin's service (`inject(EpdfRender)`, `inject(EpdfSearch)`)
found no viewer above it that has the plugin. Either there's no viewer above it at all, or the
viewer's `provideEmbedPdf()` doesn't have the plugin's feature.

Add the feature the error names to `provideEmbedPdf()`, in the component that provides the viewer
or in your app config. `withRender()` gives `EpdfRender`, `withSearch()` gives `EpdfSearch`, and
so on:

**`add-feature.ts`**

```typescript
import { Component, inject } from '@angular/core';
import { provideEmbedPdf } from '@embedpdf/angular/runtime';
import { EpdfRender, withRender } from '@embedpdf/angular/render';
import { withStage } from '@embedpdf/angular/stage';
import { engine } from './pdf';

@Component({
  selector: 'app-document-viewer',
  // withRender() is what gives the viewer EpdfRender
  providers: [provideEmbedPdf({ engine }, withStage(), withRender())],
  template: `<!-- your toolbar and pages -->`,
})
export class DocumentViewer {
  private readonly render = inject(EpdfRender);
}
```

## EPDF-103

**A layer outside a page.** Something that draws on a page, such as `<epdf-render-layer>`, isn't
inside a page. A layer needs the page it draws on, and only the Stage gives one.

Put it inside `<ng-template epdfPage>` in an `<epdf-stage>`. The Stage draws that template once
for every page on screen:

**`layer-in-page.ts`**

```typescript
import { Component } from '@angular/core';
import { EpdfRenderLayer } from '@embedpdf/angular/render';
import { EpdfPageTemplate, EpdfStage } from '@embedpdf/angular/stage';

@Component({
  selector: 'app-pages',
  imports: [EpdfStage, EpdfPageTemplate, EpdfRenderLayer],
  template: `
    <epdf-stage>
      <ng-template epdfPage>
        <!-- Drawn once on every page -->
        <epdf-render-layer />
      </ng-template>
    </epdf-stage>
  `,
})
export class Pages {}
```

## EPDF-104

**Part of a Stage outside one.** UI that belongs to a Stage, such as `<epdf-scrollbar>` or
`<epdf-anchored>`, isn't inside an `<epdf-stage>`. It scrolls that Stage, or follows its pages,
so it needs to be in it.

Put it between the Stage's tags, next to the page template. It sits over the pages, in the Stage's
own box:

**`inside-stage.ts`**

```typescript
import { Component } from '@angular/core';
import { EpdfRenderLayer } from '@embedpdf/angular/render';
import { EpdfPageTemplate, EpdfScrollbar, EpdfStage } from '@embedpdf/angular/stage';

@Component({
  selector: 'app-pages',
  imports: [EpdfStage, EpdfPageTemplate, EpdfRenderLayer, EpdfScrollbar],
  template: `
    <epdf-stage>
      <ng-template epdfPage>
        <epdf-render-layer />
      </ng-template>

      <!-- Inside the Stage, over its pages -->
      <epdf-scrollbar axis="y" />
    </epdf-stage>
  `,
})
export class Pages {}
```

## EPDF-105

**An engine call on the server.** Code called a method that needs the engine (`open()`, a page's
picture, a zoom) while Angular rendered the page on the server. The engine only runs in the
browser, so on the server the viewer renders its empty state and every such call throws.

Call it from something that only happens in the browser: an event handler (`(click)`), or
`afterNextRender()` for work when the component first shows:

**`browser-only.ts`**

```typescript
import { afterNextRender, Component, inject } from '@angular/core';
import { EpdfDocuments } from '@embedpdf/angular/runtime';

@Component({
  selector: 'app-contract',
  template: `<!-- your toolbar and pages -->`,
})
export class Contract {
  private readonly documents = inject(EpdfDocuments);

  constructor() {
    // Runs in the browser only, after the first render
    afterNextRender(() => {
      void this.documents.open({ kind: 'url', url: '/files/contract.pdf' });
    });
  }
}
```

To keep the viewer out of the server render altogether, put it in a `@defer (on viewport)`
block. See [Setup](setup#server-side-rendering).
