tinyhumansai/openhuman · error

DELETE_FAILED

DELETE_FAILED

Error message

${reason}

What it means

Returned when the openhuman.ai_delete_artifact core RPC itself throws - a transport-level failure (embedded core process gone, stale RPC port or bearer, HTTP error) or an RPC rejection such as unknown-method in a build where that surface is gated out. The core deliberately treats 'missing ArtifactMeta' and 'file already gone' as success, so DELETE_FAILED almost always means the RPC could not be completed at all, not that the target was absent.

Source

Thrown at app/src/services/artifactDownloadService.ts:330

 * `ArtifactMeta` row in the workspace registry.
 *
 * Returns `{ ok: false, error }` on any transport or RPC error
 * (network drop, core gone, unknown id, file vanished). The core
 * treats "missing meta" / "file already gone" as success.
 */
export async function deleteArtifact(artifactId: string): Promise<DeleteArtifactOutcome> {
  if (!artifactId.trim()) {
    return { ok: false, code: 'MISSING_ARTIFACT_ID', error: 'artifact id missing' };
  }
  try {
    await callCoreRpc<unknown>({
      method: 'openhuman.ai_delete_artifact',
      params: { artifact_id: artifactId },
    });
    return { ok: true };
  } catch (err) {
    const reason = err instanceof Error ? err.message : String(err);
    return { ok: false, code: 'DELETE_FAILED', error: reason };
  }
}

export async function revealArtifactInFileManager(absolutePath: string): Promise<boolean> {
  if (!isTauri()) return false;
  if (!absolutePath.trim()) return false;
  try {
    // Use the plugin's typed binding — the raw `invoke('plugin:opener|
    // reveal_item_in_dir', { path })` shape silently no-ops because the
    // plugin expects `{ paths: [absolutePath] }` (array). The binding
    // handles the wrap.
    await revealItemInDir(absolutePath);
    return true;
  } catch (err) {
    // Swallow — reveal is best-effort, the file is already saved.
    console.warn('[artifact] revealItemInDir failed:', err);
    return false;
  }

View on GitHub (pinned to 7491200858)

Solutions

  1. Read the embedded error text: connection failures point to core availability, 'unknown method' to version or feature-gating skew.
  2. Retry once after the core becomes ready again (restart_core_process or waiting for the ready signal) - boot races are the most common shape.
  3. If the method is unknown, align frontend and core versions so the ai namespace is registered.
  4. Only enable destructive UI actions after the core-ready gate has passed.

Example fix

// before
rows.remove(row); // optimistic
await deleteArtifact(id); // fire and forget

// after
rows.remove(row); // optimistic
const out = await deleteArtifact(id);
if (!out.ok) {
  rows.restore(row); // documented contract: re-insert on { ok: false }
  showError(`Delete failed: ${out.error}`);
}
Defensive patterns

Strategy: fallback

Try / catch

deleteArtifact returns DeleteArtifactOutcome rather than throwing. Follow the documented optimistic-UI contract: remove the row first, call deleteArtifact, and re-insert the row on { ok: false } so the user loses nothing when the core is unreachable.

Prevention

When it happens

Trigger: The core process crashed or was restarted while the UI held an old port or bearer; calling deleteArtifact before the embedded core reached ready state (boot race); a version or gating skew where the running core does not know the openhuman.ai_delete_artifact method.

Common situations: Deleting an artifact right after a core restart or app update; OPENHUMAN_CORE_REUSE_EXISTING pointing at a dead external core; dev iteration with a hot-reloaded frontend against a restarting core.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17). Data as JSON: /api/errors/f0d5d0396c77b986. Report an issue: GitHub.