nexu-io/open-design · error · ArtifactManifestRequiredError
ARTIFACT_MANIFEST_REQUIRED
ARTIFACT_MANIFEST_REQUIRED
Error message
artifactManifest is required for ${name}; no safe default manifest can be inferred What it means
Thrown by resolveCreateArtifactManifest() as ArtifactManifestRequiredError (code ARTIFACT_MANIFEST_REQUIRED) when no artifactManifest was supplied AND inferLegacyManifest() could not infer one from the file extension. Legacy inference only covers .html/.htm (html or deck), .md (markdown-document), and .svg (svg). Any other extension without an explicit manifest hits this.
Source
Thrown at apps/daemon/src/artifacts/create.ts:66
encoding: input.encoding === 'base64' ? 'base64' : 'utf8',
artifact: true,
overwrite: false,
...(input.artifactManifest === undefined ? {} : { artifactManifest: input.artifactManifest }),
};
}
export function resolveCreateArtifactManifest(input: CreateProjectArtifactInput): unknown {
const manifest = input.artifactManifest !== undefined && input.artifactManifest !== null
? input.artifactManifest
: inferLegacyManifest(input.name);
if (manifest) {
const validated = validateArtifactManifestInput(manifest, input.name);
if (!validated.ok) {
throw new ArtifactManifestInvalidError(validated.error);
}
return validated.value;
}
throw new ArtifactManifestRequiredError(input.name);
}
export async function createProjectArtifactFile(options: CreateProjectArtifactOptions): Promise<unknown> {
const { input } = options;
const body = input.encoding === 'base64'
? Buffer.from(input.content, 'base64')
: Buffer.from(input.content, 'utf8');
return await options.writeProjectFile(
options.projectsRoot,
options.projectId,
input.name,
body,
{
overwrite: false,
artifactManifest: resolveCreateArtifactManifest(input),
},
options.metadata,
);View on GitHub (pinned to 5be4028344)
Solutions
- Provide an explicit artifactManifest in the request body (or via --manifest for the CLI).
- Rename the file to .html/.htm/.md/.svg if you genuinely want the inferred manifest.
- For react-component/mini-app/diagram/code-snippet/design-system kinds, always supply the manifest — inference does not cover them.
Example fix
// before
await postCreateArtifactRequest({
baseUrl, projectId,
input: { name: 'widget.tsx', content, encoding: 'utf8' }
});
// after — explicit manifest for a react-component
await postCreateArtifactRequest({
baseUrl, projectId,
input: {
name: 'widget.tsx', content, encoding: 'utf8',
artifactManifest: {
kind: 'react-component',
renderer: 'react-component',
exports: ['jsx', 'zip']
}
}
}); Defensive patterns
Strategy: validation
Validate before calling
import { inferLegacyManifest } from './artifacts/manifest.js';
const needsExplicit = !inferLegacyManifest(name); // null for non-html/md/svg
if (needsExplicit && !artifactManifest) {
throw new Error(`an explicit artifactManifest is required for ${name}`);
} Type guard
const INFERABLE_EXT = new Set(['.html', '.htm', '.md', '.svg']);
function inferableFromName(name: string): boolean {
return INFERABLE_EXT.has(name.slice(name.lastIndexOf('.')).toLowerCase());
} Try / catch
try {
resolveCreateArtifactManifest(input);
} catch (e) {
if (e instanceof ArtifactManifestRequiredError) {
// prompt user for a manifest, then retry
}
throw e;
} Prevention
- Always pass an explicit artifactManifest for react-component, mini-app, diagram, code-snippet, and design-system kinds.
- If relying on inference, keep the file extension as .html/.htm/.md/.svg.
- Build the manifest upstream so the create call is deterministic.
When it happens
Trigger: POST /api/projects/:id/files with artifact=true for a file whose name ends in something other than .html/.htm/.md/.svg (e.g. .json, .tsx, .png, no extension) and no artifactManifest in the body. Same path via `od artifacts create --name foo.json` without --manifest.
Common situations: Creating a react-component / mini-app / diagram / code-snippet / design-system artifact (none of which are inferable) and forgetting the manifest; renaming a file to a custom extension; creating an artifact with no extension.
Related errors
- ARTIFACT_MANIFEST_INVALID
- ARTIFACT_PUBLICATION_BLOCKED
- sourceKind must be one of upload, url, repo, connector, arti
- ingestion body is required
- bodyMarkdown is required
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/c7e8ffc281785b4d.
Report an issue: GitHub.