Significant-Gravitas/AutoGPT · error · Error

Failed to fetch artifact

Error message

Failed to fetch artifact

What it means

ValueError raised inside _validate_resource_ownership when the StoreListing exists but its owningOrgId differs from the claimed source org. Only the listing's owning org may transfer it; this blocks creating transfers for listings owned by other organizations.

Source

Thrown at autogpt_platform/frontend/src/app/(platform)/copilot/components/ArtifactPanel/components/useArtifactContent.ts:117

      if (
        !isTransientArtifactFetchStatus(response.status) ||
        attempt === CONTENT_FETCH_MAX_RETRIES
      ) {
        throw new ArtifactFetchError(await parseArtifactFetchError(response));
      }
    } catch (error) {
      if (error instanceof ArtifactFetchError) throw error;
      if (attempt === CONTENT_FETCH_MAX_RETRIES) {
        throw error instanceof Error
          ? error
          : new Error("Failed to fetch artifact");
      }
    }

    await sleep(CONTENT_FETCH_RETRY_DELAY_MS);
  }

  throw new Error("Failed to fetch artifact");
}

export function getCachedArtifactContent(id: string): string | undefined {
  return contentCache.get(id);
}

export function clearContentCache() {
  contentCache.clear();
}

export function useArtifactContent(
  artifact: ArtifactRef,
  classification: ArtifactClassification,
) {
  const [content, setContent] = useState<string | null>(null);
  const [pdfUrl, setPdfUrl] = useState<string | null>(null);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

View on GitHub (pinned to 9c8bb5550f)

Solutions

  1. Confirm listing.owningOrgId equals the active org before submitting the transfer.
  2. Restrict transferable listings in the UI to those owned by the active org.
  3. Prompt an org switch when the user belongs to the owning org.

Example fix

# before
await create_transfer("StoreListing", lid, source_org=active_org, ...)

# after
l = await get_store_listing(lid)
if l.owning_org_id != active_org:
    raise PermissionError("Listing not owned by active org")
await create_transfer("StoreListing", lid, source_org=active_org, ...)
Defensive patterns

Strategy: type-guard

Validate before calling

l = await get_store_listing(resource_id)
if l.owning_org_id != active_org_id:
    raise PermissionError("Listing not owned by active org")

Type guard

def listing_owned_by_org(l: StoreListingResponse, org_id: str) -> bool:
    return l.owning_org_id == org_id

Try / catch

try:
    await create_transfer("StoreListing", lid, ...)
except ValueError as e:
    if "does not belong" in str(e):
        prompt_org_switch()
    else:
        raise

Prevention

When it happens

Trigger: Creating a StoreListing transfer where the caller's active org is not the listing's owningOrgId — wrong org selected, or attempting to transfer a listing the org does not own.

Common situations: Multi-org user with the wrong active org; listings visible in the store but owned by a different org; probing another org's listing id.

Related errors


AI-assisted analysis of Significant-Gravitas/AutoGPT@9c8bb5550f (2026-08-14). Data as JSON: /api/errors/7fcbba32fd8cd4d0. Report an issue: GitHub.