-
Notifications
You must be signed in to change notification settings - Fork 23
Description
Summary
sdk.processes.invoke() has three separate issues that make it unusable for invoking specific entry points in multi-function packages: (1) EntryPointPath is silently ignored, (2) the method returns immediately after HTTP 201 without waiting for the job to complete, and (3) the correct folder context header is undocumented.
Root Cause
Part 1 — EntryPointPath silently ignored
The SDK's _invoke_spec builds {"ReleaseName": name, **(input_data or {})}. There is no slot for EntryPointPath. The **kwargs in invoke() extract only parent_span_id; all other kwargs are silently dropped.
# This has NO effect:
job = sdk.processes.invoke(
name="invoice-tools",
input_arguments={"blob_file_path": "invoices/inv001.pdf"},
EntryPointPath="invoice_tools/extract.py:extract_invoice_data" # silently ignored
)The wrong (default) entry point runs. sdk.jobs.extract_output() returns None because the output schema doesn't match.
Part 2 — Fire-and-forget (no wait mechanism)
sdk.processes.invoke() returns after HTTP 201 (job queued), not after the job completes. Calling sdk.jobs.extract_output() on a still-running job returns None with no indication that the job hasn't finished.
Part 3 — Folder header undocumented
When calling the Orchestrator StartJobs API directly, the correct header is x-uipath-folderkey (not X-UIPATH-FolderPath). The Orchestrator runtime injects UIPATH_FOLDER_KEY as the env var. Using an empty X-UIPATH-FolderPath header produces HTTP 400 "A folder is required for this action" (errorCode 1101).
Current Workaround
Bypass the SDK entirely and poll manually:
folder_key = os.getenv("UIPATH_FOLDER_KEY", "")
headers = {
"Authorization": f"Bearer {token}",
"x-uipath-folderkey": folder_key,
}
payload = {"startInfo": {
"ReleaseName": process_name,
"EntryPointPath": "invoice_tools/extract.py:extract_invoice_data",
"InputArguments": json.dumps(input_args),
}}
resp = httpx.post(
f"{base_url}/orchestrator_/odata/Jobs/UiPath.Server.Configuration.OData.StartJobs",
json=payload, headers=headers
)
job_key = resp.json()["value"][0]["Key"]
# Poll until terminal state
while True:
job = sdk.jobs.retrieve(job_key)
if job.state.lower() in {"successful", "faulted", "stopped", "abandoned"}:
break
time.sleep(2)
output_str = sdk.jobs.extract_output(job)
return json.loads(output_str)Note: job.state is lowercase ("successful", "faulted") — not documented.
Suggested Fix
- Add
entry_point: Optional[str] = Nonetosdk.processes.invoke()and include it in the StartJobs payload - Add
wait: bool = True(orpoll_interval: float = 2.0) that polls until the job reaches a terminal state before returning - Document that
UIPATH_FOLDER_KEY(notUIPATH_FOLDER_PATH) is injected by the Orchestrator runtime, and that the correct header isx-uipath-folderkey - Document the valid
job.statevalues (lowercase strings) and which are terminal
Impact
- Severity: High
- Multi-function packages (the primary use case for
uipath functions) cannot be invoked via the SDK - Three separate silent failures make this extremely hard to debug