nexu-io/open-design · warning · Error

artifactType must be one of: ${Object.keys(openDesignBriefCa

Error message

artifactType must be one of: ${Object.keys(openDesignBriefCatalog).join(', ')}

What it means

readArtifactType rejects any value that is not a string key of openDesignBriefCatalog (packages/contracts/src/api/brief.ts), which defines exactly eight artifact types such as website and product-prototype. The thrown message enumerates the accepted keys at runtime, so the canonical list is whatever the current catalog exposes.

Source

Thrown at apps/daemon/src/mcp-brief.ts:510

          ? { externalPluginContext: draft.externalPluginContext }
          : {}),
      };
      draft.confirmation = confirmation;
      draft.confirmationAnswersDigest = confirmationAnswersDigest;
      if (draft.pluginWorkflowId && draft.briefState !== 'skipped') {
        draft.briefState = 'confirmed';
      }
      return confirmation;
    },
  };
}

function readArtifactType(value: unknown): OpenDesignBriefArtifactType {
  if (
    typeof value !== 'string'
    || !Object.hasOwn(openDesignBriefCatalog, value)
  ) {
    throw new Error(
      `artifactType must be one of: ${Object.keys(openDesignBriefCatalog).join(', ')}`,
    );
  }
  return value as OpenDesignBriefArtifactType;
}

export function readBriefLocale(value: unknown): LocalMcpBriefLocale {
  if (typeof value !== 'string' || value.trim().length === 0) return 'en';
  const normalized = value.trim().replaceAll('_', '-').toLowerCase();
  if (normalized === 'zh' || normalized === 'zh-cn' || normalized.startsWith('zh-hans')) {
    return 'zh-CN';
  }
  if (
    normalized === 'zh-tw'
    || normalized === 'zh-hk'
    || normalized === 'zh-mo'
    || normalized.startsWith('zh-hant')
  ) {

View on GitHub (pinned to 5be4028344)

Solutions

  1. Pass one of the keys printed in the error message.
  2. Source the allowed set from OPEN_DESIGN_BRIEF_ARTIFACT_TYPES in @open-design/contracts instead of hardcoding.
  3. Align the contracts dependency version with the daemon.

Example fix

// before
collect_brief({ artifactType: 'web-site' }) // typo -> throws [364]

// after
collect_brief({ artifactType: 'website' })
Defensive patterns

Strategy: type-guard

Validate before calling

import { OPEN_DESIGN_BRIEF_ARTIFACT_TYPES } from '@open-design/contracts';
const valid = new Set(OPEN_DESIGN_BRIEF_ARTIFACT_TYPES);
if (!valid.has(artifactType)) {
  throw new Error(`artifactType must be one of: ${[...valid].join(', ')}`);
}

Type guard

import { OPEN_DESIGN_BRIEF_ARTIFACT_TYPES } from '@open-design/contracts';
function isArtifactType(v: unknown): v is OpenDesignBriefArtifactType {
  return typeof v === 'string' && OPEN_DESIGN_BRIEF_ARTIFACT_TYPES.includes(v as any);
}

Prevention

When it happens

Trigger: Passing artifactType as undefined, a number, an empty string, a typo, or a value from an older or newer version whose catalog keys differ.

Common situations: Version skew between the contracts package the caller hardcoded and the daemon's catalog; free-text artifactType supplied by an LLM.

Related errors


AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12). Data as JSON: /api/errors/743be0530131c3e7. Report an issue: GitHub.