apereo/cas · error · Error

Resource ID already exists in namespace .

Error message

Resource ID ${id} already exists in namespace ${payload.namespace}.

What it means

Client-side guard in the Palantir Heimdall resource editor. Before saving a resource it checks the in-memory catalog for an existing resource with the same numeric ID in the same namespace; if one exists (and is not the resource being edited), it throws. This prevents duplicate resource IDs within a namespace in the authorization service.

Solutions

  1. Pick a resource ID not already used in the target namespace
  2. Verify which namespace you are saving into; the ID may be free in a different namespace
  3. If editing, reopen the dialog so the original-id is tracked and the existing resource is updated instead of created

Example fix

// before
$('#heimdallResourceId').val(42); // 42 already exists in namespace
// after
const taken = (catalog[payload.namespace] ?? []).some(r => Number(r.id) === 42);
$('#heimdallResourceId').val(taken ? nextFreeId(catalog, payload.namespace) : 42);
Defensive patterns

Strategy: validation

Validate before calling

const catalog = dialog.data("resource-catalog") ?? {};
const id = Number($("#heimdallResourceId").val());
const taken = (catalog[payload.namespace] ?? []).some(r => Number(r.id) === id && Number(r.id) !== Number(originalId));
if (taken) { alert(`ID ${id} is already used in namespace ${payload.namespace}`); return; }

Type guard

const isIdFree = (catalog, namespace, id, exceptId) =>
  !(catalog?.[namespace] ?? []).some(r => Number(r.id) === Number(id) && Number(r.id) !== Number(exceptId));

Try / catch

try { storeHeimdallResources(payload); } catch (e) { if (/already exists in namespace/.test(e.message)) { alert('Choose a different resource ID'); } else { throw e; } }

Prevention

When it happens

Trigger: Submitting the Heimdall resource dialog with a resource ID that already exists in the selected namespace, or editing a resource and changing its ID to collide with another resource in that namespace.

Common situations: Re-importing a resource definition with a fixed ID, copy-pasting resource JSON and forgetting to change the ID, or two admins assigning the same numeric ID in one namespace.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08). Data as JSON: /api/errors/89542be4bbba243f. Report an issue: GitHub.

Appendix: source

Thrown at support/cas-server-support-thymeleaf/src/main/resources/static/js/palantir-authz.js:855

    const showEditor = $("#showHeimdallResourceJsonEditor").val() === "true";
    localStorage.setItem(HEIMDALL_EDITOR_PREFERENCE, String(showEditor));
    $("#heimdallResourceEditorContainer").toggle(showEditor);
    $("#heimdallResourceControls").toggleClass("heimdall-resource-controls-expanded", !showEditor);
    if (showEditor && typeof ace !== "undefined") {
        setTimeout(() => ace.edit("heimdallResourceEditor").resize(true), 50);
    }
}

function validateHeimdallResourceIdentity(payload) {
    const dialog = $("#newHeimdallResourceDialog");
    const editMode = dialog.data("edit-mode") === true;
    const originalId = dialog.data("original-id");
    const catalog = dialog.data("resource-catalog") ?? {};
    const id = Number($("#heimdallResourceId").val());
    const duplicate = (catalog[payload.namespace] ?? []).some(resource => Number(resource.id) === Number(id)
        && (!editMode || Number(resource.id) !== Number(originalId)));
    if (duplicate) {
        throw new Error(`Resource ID ${id} already exists in namespace ${payload.namespace}.`);
    }
}

function storeHeimdallResources(payload) {
    return $.ajax({
        url: `${CasActuatorEndpoints.heimdall()}/resources`,
        method: "POST",
        contentType: "application/json",
        data: JSON.stringify(payload)
    });
}

function prefillHeimdallResourceDialog(resource) {
    $("#heimdallResourceId").val(resource.id);
    $("#heimdallResourcePattern").val(resource.pattern ?? "");
    $("#heimdallResourceMethod").val(resource.method ?? "");
    setHeimdallSwitchState("heimdallEnforceAllPolicies", resource.enforceAllPolicies === true);
    prefillHeimdallResourceProperties(resource.properties);

View on GitHub (pinned to e7288fc434)