# Search Indexing Errors

> This alert triggers when a search definition's latest index build reported errors in PTSF_INDEX_STAT or PTSF_ES_DT_ERR, or rows failed Real-Time Indexing.

---

Site [llms.txt](/llms.txt)

---

<div class="alert alert-warning border shadow-sm mb-4 psl-prospect-cta" role="note">
  <div class="d-flex flex-column flex-lg-row align-items-lg-center justify-content-between gap-3">
    <div>
      <strong>New to psLens?</strong> This page documents one specific alert. To see how it appears on the dashboard,
      what operators investigate, and how teams tune it, start with a live walkthrough.
    </div>
    <div class="d-flex flex-wrap gap-2">
      <a class="btn btn-sm btn-primary" href="/contact/">Book a Demo</a>
      <a class="btn btn-sm btn-outline-primary" href="/docs/alerts/">Browse Alerts</a>
    </div>
  </div>
</div><div id="pslens-context-panel" class="card border-info mb-4 d-none">
  <div class="card-header bg-light text-info py-2 fw-bold d-flex align-items-center border-bottom border-info-subtle">
    <i class="bi bi-info-circle-fill me-2"></i>
    <span>Tailored Operational Context</span>
  </div>
  <div class="card-body p-0">
    <ul class="list-group list-group-flush">
      <li id="row-db" class="list-group-item d-flex align-items-center justify-content-between py-2 d-none">
        <strong>Target Database:</strong>
        <span id="ctx-db" class="badge bg-secondary font-monospace">&mdash;</span>
      </li>
      <li id="row-type" class="list-group-item d-flex align-items-center justify-content-between py-2 d-none">
        <strong>Context Type:</strong>
        <span id="ctx-type" class="badge bg-light text-dark border font-monospace text-uppercase">&mdash;</span>
      </li>
      <li id="row-severity" class="list-group-item d-flex align-items-center justify-content-between py-2 d-none">
        <strong>Alert Severity:</strong>
        <span id="ctx-severity" class="badge">&mdash;</span>
      </li>
      <li id="row-time" class="list-group-item d-flex align-items-center justify-content-between py-2 d-none">
        <strong>Triggered Time:</strong>
        <span id="ctx-time" class="text-muted small">&mdash;</span>
      </li>
      <li id="row-details" class="list-group-item py-2 d-none">
        <strong id="label-details" class="d-block mb-1">Firing Context:</strong>
        <code id="ctx-details" class="d-block p-2 bg-light border rounded small"
          style="white-space: pre-wrap; word-break: break-all;">&mdash;</code>
      </li>
      <li id="row-sql" class="list-group-item py-2 d-none">
        <div class="d-flex justify-content-between align-items-center mb-1">
          <strong id="label-sql">Contextual SQL:</strong>
          <button id="btn-copy-sql" type="button" class="btn btn-sm btn-outline-secondary py-0 px-2 small">
            <i class="bi bi-clipboard me-1"></i>Copy SQL
          </button>
        </div>
        <pre class="mb-0 p-2 bg-light border rounded small"><code id="ctx-sql" style="white-space: pre-wrap; word-break: break-word;">&mdash;</code></pre>
      </li>
    </ul>
  </div>
</div>

<script>
  (function () {
    const params = new URLSearchParams(window.location.search);
    const metadata = params.get('metadata');
    if (!metadata) return;

    try {
      
      const base64 = metadata.replace(/-/g, '+').replace(/_/g, '/');
      const jsonStr = decodeURIComponent(escape(window.atob(base64)));
      const data = JSON.parse(jsonStr);

      if (data) {
        let hasData = false;

        if (data.db) {
          document.getElementById('ctx-db').textContent = data.db;
          document.getElementById('row-db').classList.remove('d-none');
          hasData = true;
        }

        if (data.type) {
          document.getElementById('ctx-type').textContent = data.type;
          document.getElementById('row-type').classList.remove('d-none');
          hasData = true;
        }

        if (data.severity) {
          const severityBadge = document.getElementById('ctx-severity');
          const severity = data.severity.toLowerCase();
          severityBadge.textContent = severity.toUpperCase();
          if (severity === 'critical') {
            severityBadge.className = 'badge bg-danger';
          } else if (severity === 'warning') {
            severityBadge.className = 'badge bg-warning text-dark';
          } else {
            severityBadge.className = 'badge bg-info';
          }
          document.getElementById('row-severity').classList.remove('d-none');
          hasData = true;
        }

        if (data.t) {
          const date = new Date(data.t * 1000);
          document.getElementById('ctx-time').textContent = date.toLocaleString();
          document.getElementById('row-time').classList.remove('d-none');
          hasData = true;
        }

        if (data.details) {
          document.getElementById('ctx-details').textContent = data.details;

          
          const labelDetails = document.getElementById('label-details');
          if (data.type === 'object') {
            labelDetails.textContent = 'Object Metadata Details:';
          } else if (data.type === 'report') {
            labelDetails.textContent = 'Report Description:';
          } else {
            labelDetails.textContent = 'Firing Context:';
          }

          document.getElementById('row-details').classList.remove('d-none');
          hasData = true;
        }

        if (data.sql) {
          document.getElementById('ctx-sql').textContent = data.sql;
          document.getElementById('row-sql').classList.remove('d-none');
          const copyBtn = document.getElementById('btn-copy-sql');
          if (copyBtn && navigator.clipboard) {
            copyBtn.addEventListener('click', function () {
              navigator.clipboard.writeText(data.sql).then(function () {
                copyBtn.innerHTML = '<i class="bi bi-check2 me-1"></i>Copied';
                setTimeout(function () {
                  copyBtn.innerHTML = '<i class="bi bi-clipboard me-1"></i>Copy SQL';
                }, 2000);
              });
            });
          }
          hasData = true;
        }

        if (hasData) {
          document.getElementById('pslens-context-panel').classList.remove('d-none');
        }
      }
    } catch (e) {
      console.error('Failed to parse operational context metadata:', e);
    }
  })();
</script>

## Search Indexing Errors Alert

**Alert ID:** `ptsf_indexing_errors`
**Category:** Search Framework
**Default lookback:** 24 hours
**Runs:** every 15 minutes

### What This Alert Detects

This alert triggers when PeopleSoft has recorded indexing errors for a search definition. It reads three sources:

|      Source       |                   What it holds                    |        Scope        |
| ----------------- | -------------------------------------------------- | ------------------- |
| `PTSF_INDEX_STAT` | The error count an index build reported            | Latest build only   |
| `PTSF_ES_DT_ERR`  | Requests the search engine rejected during a build | Latest build only   |
| `PTSF_INDDATA_ER` | Rows that failed Real-Time Indexing                | Within the lookback |

"Latest build" is the build recorded for the definition in `PTSF_SCHED_STAT`. A clean rebuild clears the first two sources, so the alert resolves on its own.

### Severity Logic

|                   Condition                   | Severity |
| --------------------------------------------- | -------- |
| Any source has errors for a search definition | Warning  |

There is one alert item per search definition, listing each source that has errors.

### Alert Details

Each alert item includes:

- The search definition
- The error count the latest build reported
- The number of requests the search engine rejected
- The number of rows that failed Real-Time Indexing in the lookback window
- A link to the Search Framework Monitor

### Configuration

```yaml
alerts:
  checks:
    ptsf_indexing_errors:
      enabled: true
      lookbackHours: 24    # Window for failed Real-Time Indexing rows
```

|     Setting     | Default |                        Description                        |
| --------------- | ------- | --------------------------------------------------------- |
| `lookbackHours` | `24`    | How far back to count rows that failed Real-Time Indexing |

### How to Respond

1. Open the [Search Framework Monitor](/docs/monitor/search-framework/) and switch on the **Indexing Errors** panel. It shows the first part of the search engine's response for each rejected request, and the record and keys of each failed row.
2. Follow the process instance link to Process Monitor for the build's message log.
3. Fix the cause the search engine reports, then rebuild the index for the definition.

### What This Alert Cannot See

A build that ends in Success with no recorded errors is not flagged, even if it indexed nothing. PeopleSoft can leave its document counts at zero after a successful build, so a zero count is not treated as an error. Check the document count in the search engine.

### Required Tables

Each source is read only when its table is whitelisted. `PTSF_INDEX_STAT` and `PTSF_ES_DT_ERR` also need `PTSF_SCHED_STAT`. With no source available the alert is inactive.
