tinyhumansai/openhuman · error

Apify run finished with status

Error message

Apify run finished with status: {status}

What it means

After posting a run to /agent-integrations/apify/run, the response's status field must be "SUCCEEDED"; any other value (FAILED, TIMED-OUT, ABORTED, or UNKNOWN when the field is missing) bails with 'Apify run finished with status: {status}'. The HTTP call itself succeeded - it is the actor run's outcome that failed. The code then expects an items array, so a malformed success response surfaces as a different error.

Solutions

  1. Read the status value: FAILED or TIMED_OUT usually mean input or target problems - check the actor's run log on Apify.
  2. Validate the input (target URL or profile identifier) before triggering the run.
  3. Verify the Apify integration credentials are current.
  4. Retry with backoff for transient blocks or platform hiccups.
Defensive patterns

Strategy: retry

Try / catch

Retry the Apify run with capped exponential backoff (e.g. 2-3 attempts) when the status is TIMED-OUT or a transient-looking FAILED; give up on ABORTED or repeated FAILED and degrade gracefully - the run's status, not the HTTP call, is what failed.

Prevention

When it happens

Trigger: The Apify actor fails on bad input (e.g. an unreachable or protected profile URL), times out, or aborts; missing or expired Apify integration credentials cause a failed run; response shape drift where the status field is absent yields UNKNOWN.

Common situations: Scraping targets that block the actor; Apify account quota or rate limits exhausted; the sought data simply unavailable for the target.

Related errors


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

Appendix: source

Thrown at src/openhuman/agent/learning/linkedin_enrichment.rs:659

        actor = LINKEDIN_SCRAPER_ACTOR,
        url_len = profile_url.len(),
        "[linkedin_enrichment] invoking Apify actor"
    );

    // The backend wraps the Apify response in its standard envelope.
    // `IntegrationClient::post` already unwraps `{ success, data }`.
    let resp: serde_json::Value = client
        .post("/agent-integrations/apify/run", &body)
        .await
        .map_err(|e| anyhow::anyhow!("Apify run failed: {e:#}"))?;

    let status = resp
        .get("status")
        .and_then(|v| v.as_str())
        .unwrap_or("UNKNOWN");

    if status != "SUCCEEDED" {
        anyhow::bail!("Apify run finished with status: {status}");
    }

    // Extract the first item from the inline results array.
    let items = resp
        .get("items")
        .and_then(|v| v.as_array())
        .ok_or_else(|| anyhow::anyhow!("Apify run returned no items array"))?;

    items
        .first()
        .cloned()
        .ok_or_else(|| anyhow::anyhow!("Apify run returned an empty items array"))
}

/// Build a local memory client for profile persistence.
fn build_memory_client() -> anyhow::Result<tinymemory_core::store::MemoryClient> {
    tinymemory_core::store::MemoryClient::new_local()
        .map_err(|e| anyhow::anyhow!("memory client unavailable: {e}"))

View on GitHub (pinned to 7491200858)