tinyhumansai/openhuman · error
MISSING_ARTIFACT_ID
MISSING_ARTIFACT_ID
Error message
artifact id missing
What it means
resolveArtifactForExport trims the artifactId argument; if it is empty or whitespace-only it returns (does NOT throw) a result object { ok: false, code: 'MISSING_ARTIFACT_ID', error: 'artifact id missing' }. Callers of downloadArtifact / the Save-As path must branch on ok, not use try/catch - this is a typed outcome, part of the DownloadArtifactOutcome/ResolveExportResult discriminated union.
Source
Thrown at app/src/services/artifactDownloadService.ts:191
return { ok: true, artifacts };
} catch (err) {
const reason = err instanceof Error ? err.message : String(err);
return { ok: false, artifacts: [], error: reason };
}
}
/**
* Resolve an artifact's absolute on-disk path (via `ai_get_artifact`)
* and build the suggested filename. Shared by the Save-As and Downloads
* export paths so both apply identical title/extension handling.
*/
async function resolveArtifactForExport(
artifactId: string,
fallbackTitle: string,
extension: string
): Promise<ResolveExportResult> {
if (!artifactId.trim()) {
return { ok: false, code: 'MISSING_ARTIFACT_ID', error: 'artifact id missing' };
}
let resolved: AiGetArtifactData;
try {
const raw = await callCoreRpc<AiGetArtifactData>({
method: 'openhuman.ai_get_artifact',
params: { artifact_id: artifactId },
});
resolved = raw ?? {};
} catch (err) {
const reason = err instanceof Error ? err.message : String(err);
return { ok: false, code: 'RESOLVE_FAILED', error: reason };
}
const sourcePath = resolved.absolute_path;
if (!sourcePath) {
return {
ok: false,View on GitHub (pinned to 7491200858)
Solutions
- Pass the real artifact id from the artifact record (the same id accepted by openhuman.ai_get_artifact)
- Guard at the call site: hide/disable the download control when the id is blank
- If the id should exist, trace why the owning payload lacks it - this error is always a caller-side data bug
Example fix
// before
downloadArtifact(artifact.artifactId ?? '', artifact.title, 'md');
// after - do not offer the action without an id
if (!artifact.artifactId?.trim()) return null; // or hide the button
return <DownloadButton onClick={() => void downloadArtifact(artifact.artifactId!, artifact.title, 'md')} />; Defensive patterns
Strategy: validation
Validate before calling
// Guard before calling into the export path
if (typeof artifactId !== 'string' || !artifactId.trim()) {
// do not open the dialog / do not call downloadArtifact
return;
} Type guard
// Narrow the outcome the service returns
const isMissingId = (o: DownloadArtifactOutcome): o is { ok: false; code: 'MISSING_ARTIFACT_ID'; error: string } =>
!o.ok && o.code === 'MISSING_ARTIFACT_ID'; Prevention
- Never call downloadArtifact with a defaulted '' id - hide the affordance instead
- Branch on the returned ok/code fields; MISSING_ARTIFACT_ID is not thrown, so try/catch will not see it
- Treat this code as a caller-side data bug and fix the missing id at its source
When it happens
Trigger: Calling downloadArtifact or the Save-As flow with an empty string, whitespace, or an undefined id stringified - e.g. an artifact row whose artifactId field is missing in the message payload that spawned the download button.
Common situations: UI rendering a download button for an artifact reference before the id arrives; artifact objects built from partial RPC data where artifact_id was never set; defensive default '' values flowing into the export path.
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
- RESOLVE_FAILED
- MISSING_ARTIFACT_PATH
- mascot manifest: missing mascots array
- mascot manifest: no renderable mascots
- audio blob is empty
AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17).
Data as JSON: /api/errors/3396926086893f47.
Report an issue: GitHub.