affaan-m/ECC · error · Error

Invalid installState identity: expected targetId and…

Error message

Invalid installState identity: expected targetId and targetRoot

What it means

normalizeInstallStateIdentity requires an object with targetId and targetRoot. When the identity argument is missing entirely, not an object (string, number, array), or null/undefined, this generic message is thrown before field-level checks run. The per-field variants (targetId/targetRoot empty) come later, so this error specifically means the identity itself was absent or the wrong type.

Solutions

  1. Pass an object: { targetId, targetRoot } with both non-empty strings
  2. If you have a full install-state record, pass state.identity (or build identity from target.id and target.root)
  3. Check the earlier lookup that produced the value — it returned undefined, so fix the lookup or guard against it
  4. Read the function signature to confirm whether identity is a separate argument or nested in options

Example fix

// before
getInstallState(record); // whole record, not identity
// after
getInstallState({ targetId: record.target.id, targetRoot: record.target.root });
Defensive patterns

Strategy: type-guard

Validate before calling

function isValidIdentity(x) {
  return x !== null && typeof x === 'object' && !Array.isArray(x);
}
if (!isValidIdentity(identity)) {
  throw new Error('installState identity object required');
}

Type guard

function isIdentity(x) {
  return typeof x === 'object' && x !== null && 'targetId' in x && 'targetRoot' in x;
}

Try / catch

try {
  return getInstallState(identity);
} catch (err) {
  if (err.message.includes('Invalid installState identity')) {
    console.error('Identity missing — resolve target before querying state');
    return null;
  } throw err;
}

Prevention

When it happens

Trigger: Calling an installState query/upsert without the identity argument; passing the record instead of its identity sub-object; passing an array of identities; forwarding an undefined variable because an earlier lookup returned nothing.

Common situations: API misuse after a refactor moved identity out of the options object; destructuring an empty row from a previous query and passing the result; scripts passing a target path string where an identity object is expected.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/87c35b46f84c6220. Report an issue: GitHub.

Appendix: source

Thrown at scripts/lib/state-store/queries.js:353

function normalizeInstallStateInput(installState) {
  return {
    targetId: installState.targetId,
    targetRoot: installState.targetRoot,
    profile: installState.profile ?? null,
    modules: installState.modules === undefined || installState.modules === null
      ? []
      : installState.modules,
    operations: installState.operations === undefined || installState.operations === null
      ? []
      : installState.operations,
    installedAt: installState.installedAt || new Date().toISOString(),
    sourceVersion: installState.sourceVersion ?? null,
  };
}

function normalizeInstallStateIdentity(identity) {
  if (!identity || typeof identity !== 'object') {
    throw new Error('Invalid installState identity: expected targetId and targetRoot');
  }

  const targetId = identity.targetId;
  const targetRoot = identity.targetRoot;
  if (typeof targetId !== 'string' || targetId.length === 0) {
    throw new Error('Invalid installState identity: targetId must be a non-empty string');
  }
  if (typeof targetRoot !== 'string' || targetRoot.length === 0) {
    throw new Error('Invalid installState identity: targetRoot must be a non-empty string');
  }

  return { targetId, targetRoot };
}

function normalizeGovernanceEventInput(governanceEvent) {
  return {
    id: governanceEvent.id,
    sessionId: governanceEvent.sessionId ?? null,

View on GitHub (pinned to 8321021c54)