# Message Catalogs

> Browse PeopleSoft Message Catalog entries — message set/number pairs with text, severity, and usage analysis.

---

LLMS index: [llms.txt](/llms.txt)

---

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


## What It Is

The Message Catalog is PeopleSoft's centralized store of user-facing text. Every `MsgGet()` call, error dialog, warning, and translated label resolves to a message set + message number pair stored in `PSMSGCATDEFN`. psLens lets you browse messages by set number, jump directly to a specific set/number, or search by message text. Each message gets a dedicated detail page with its severity, text, explanation, and a usage analysis that finds where it is referenced in PeopleCode and SQL.

## Search Page

URL: `/messagecatalogs?db={database}`

<figure><img src="/images/screenshots/metadata/message-catalogs-search.png"
    alt="Message Catalog search for set 18 showing messages in the set"><figcaption>
      <p>Browsing all messages in set 18</p>
    </figcaption>
</figure>


The search page has three entry points: enter a **Set Number** to see every message in the set, enter free text to **Search Message Text**, or punch in a specific **Set/Number pair** to jump straight to that message. The page also surfaces the highest set numbers in use (handy for picking the next free set when creating customizations) and the most recently modified messages.

## Detail Page

URL: `/messagecatalogs/{SET}/{NUMBER}?db={database}`

<figure><img src="/images/screenshots/metadata/message-catalogs-detail.png"
    alt="Detail page for message 18/1"><figcaption>
      <p>Detail page for message <code>18/1</code></p>
    </figcaption>
</figure>


The detail page has no sidebar toggles; everything loads inline. The main pane shows **Message Properties** (set, number, severity, last-updated), the full **Message Text** (with `%1`, `%2` substitution markers preserved), and the **Description / Explanation** body text developers see when investigating a message.

<figure><img src="/images/screenshots/metadata/message-catalogs-detail-expanded.png"
    alt="Full message detail page including usage analysis"><figcaption>
      <p>Full message page including usage analysis</p>
    </figcaption>
</figure>


## Usage Analysis

<figure><img src="/images/screenshots/metadata/message-catalogs-panel-usage.png"
    alt="Usage Analysis panel for the message"><figcaption>
      <p>Where this message is referenced in PeopleCode and SQL</p>
    </figcaption>
</figure>


The **Usage Analysis** card automatically scans every PeopleCode program and SQL object in the database for textual references to this set/number pair: `MsgGet(18, 1, ...)`, `MsgGetText(18, 1, ...)`, `SQLExec("...18, 1...")`, and so on. Each hit links to the parent object's detail page. Lets you find every MsgGet / MsgGetText / SQLExec call site for the set/number pair before editing the text.

## What This Consolidates

In PIA:

- Open **PeopleTools → Utilities → Administration → Message Catalog** and search by set
- Walk pages of messages to find the one you want
- Read the message text and explanation
- For usage analysis: run a separate Find In across all PeopleCode

In psLens, the Set/Number jump-to-message is one form submit, and usage analysis runs automatically. The recently-modified list also lets you spot customizations made to delivered messages, a common audit question.
