UiPath Documentation
functions
latest
false
Guia do usuário de funções
  • Visão geral
    • Sobre funções
  • Funções do Python
  • Implantar e executar

Resource bindings

Resource bindings in Python functions: how a declared platform resource is remapped to the target tenant at runtime, and why bindings are maintained by hand.

A resource binding is a declared reference to a platform resource that the runtime can remap. When a function reads an Orchestrator asset or calls an Integration Service connection, it names that resource with an identifier fixed at design time. The binding turns that identifier into a declared dependency of the package rather than a hardcoded string, so the same package can run in another tenant against that tenant's own resource.

Bindings are declared in bindings.json at the project root, and they are read both during a local run and during a job run in Orchestrator.

Why a resource identifier is not a function input

A connection id, asset name, or bucket name identifies infrastructure, not data. Passing one through Input works mechanically, but it has three consequences:

  • Every caller has to know the target tenant's configuration.
  • The override mechanism never runs, because the identifier arrives as data rather than as a declared dependency.
  • The package no longer declares that it needs the resource, so deployment tooling cannot inventory or remap it.

A binding keeps the identifier out of the invocation contract and inside the package manifest, where deployment tooling can see it.

How a binding resolves at runtime

Each SDK call that supports overrides resolves its resource in four stages:

  1. The platform supplies the mapping configured for the current tenant, one entry per declared binding.
  2. The SDK method reads its own resource identifier from the call arguments.
  3. When that identifier matches a declared binding with a mapping, the SDK substitutes the mapped value before issuing the request.
  4. When no mapping matches, the call proceeds with the design-time identifier.

The fourth stage is a silent fallback, recorded in the run log:

No resource overwrite matched for connection key='connection.<design-time-id>' on retrieve
No resource overwrite matched for connection key='connection.<design-time-id>' on retrieve

A local run has no mappings configured, so this line appears for every binding and is expected there. The same line in a job running in a target tenant means the binding was never mapped in that tenant, and the function is reaching for the design-time resource instead.

AVISO:

An unmapped binding does not fail the job. Because the call falls back to the design-time identifier, a function deployed to another tenant can attempt to reach the original tenant's resource.

The bindings.json file

Each entry in the resources array declares one resource. A connection binding looks like this:

{
  "$schema": "https://cloud.uipath.com/draft/2024-12/bindings",
  "version": "2.0",
  "resources": [
    {
      "resource": "connection",
      "key": "00000000-0000-0000-0000-000000000000",
      "value": {
        "ConnectionId": {
          "defaultValue": "00000000-0000-0000-0000-000000000000",
          "isExpression": false,
          "displayName": "Microsoft Outlook 365 Connection"
        },
        "Connector": {
          "defaultValue": "uipath-microsoft-outlook365",
          "isExpression": false,
          "displayName": "Connector"
        }
      },
      "metadata": {
        "Connector": "uipath-microsoft-outlook365",
        "UseConnectionService": "True",
        "BindingsVersion": "2.2"
      }
    }
  ]
}
{
  "$schema": "https://cloud.uipath.com/draft/2024-12/bindings",
  "version": "2.0",
  "resources": [
    {
      "resource": "connection",
      "key": "00000000-0000-0000-0000-000000000000",
      "value": {
        "ConnectionId": {
          "defaultValue": "00000000-0000-0000-0000-000000000000",
          "isExpression": false,
          "displayName": "Microsoft Outlook 365 Connection"
        },
        "Connector": {
          "defaultValue": "uipath-microsoft-outlook365",
          "isExpression": false,
          "displayName": "Connector"
        }
      },
      "metadata": {
        "Connector": "uipath-microsoft-outlook365",
        "UseConnectionService": "True",
        "BindingsVersion": "2.2"
      }
    }
  ]
}
CampoFinalidade
resourceThe resource type: asset, bucket, queue, process, app, index, connection, or mcpServer.
keyThe binding's identifier, matched against the identifier in the SDK call.
valueThe design-time values the runtime remaps. Connections carry ConnectionId and Connector; other types carry name and folderPath.
metadataDescriptive fields the platform reads when it resolves and displays the binding.

The key format depends on the resource type. Connections use the connection id on its own. Every other type joins the resource name and folder path with a dot, as in my_asset.Finance, and drops the separator when no folder path applies.

The design-time identifier appears in three places that must agree: the literal in your function code, the binding's key, and the defaultValue of the identifying field inside value. A mismatch between them means the override lookup finds nothing and the fallback applies.

SDK calls that participate in resource overrides

Only the calls below are remapped. An identifier passed to any other method is used exactly as written.

SDK callResource typeIdentificador
assets.retrieve, assets.retrieve_credentialassetFirst positional argument, joined with folder_path
buckets.* (all methods)bucketname, joined with folder_path
queues.create_item, create_items, create_transaction_itemqueueQueue name, joined with folder_path
processes.invoke, jobs.resumeprocessname or process_name, joined with folder_path
tasks.create, tasks.retrieveappapp_name, joined with app_folder_path
context_grounding.* (all methods)indexname, joined with folder_path
connections.retrieveconnectionFirst positional argument, used on its own
mcp.retrievemcpServerslug, joined with folder_path

The synchronous and asynchronous variants of each method behave identically. Calls to llm, documents, entities, guardrails, attachments, and folders produce no bindings, and neither does assets.update.

Why bindings are not derived from your code

uipath init creates bindings.json with the required structure when the file is absent, and leaves an existing file untouched. It does not read resource calls out of your code, so re-running it after a change to Input, Output, or a resource call does not update bindings. The file is maintained by hand.

Resource names are not always knowable before the function runs. A literal such as sdk.assets.retrieve("SMTP_HOST") is detectable by static analysis, but sdk.assets.retrieve(input.asset_name) or a name read from an environment variable has no value to bind at analysis time.

Because the tooling cannot distinguish an unresolvable name from a project that intentionally declares nothing, partial inference would silently discard hand-written entries, and the loss would surface only as a deployment failure in the target tenant. Leaving the file untouched is the safer behavior.

Dica:

The UiPath skills for coding agents include a bindings reference that a coding agent can follow to keep bindings.json in step with your code. See github.com/UiPath/skills.

Moving a function between tenants

Bindings are what make a single package deployable to more than one tenant. When a function project belongs to a solution, the solution aggregates the bindings declared by each of its projects into a resource list, and deployment maps every entry in that list to a resource in the target tenant.

Two commands establish that link:

The result is one .nupkg that runs unchanged in development, test, and every customer tenant, because the identifiers it carries are remapped rather than fixed.

Próximas Etapas

Esta página foi útil?

Conectar

Precisa de ajuda? Suporte

Quer aprender? Academia UiPath

Tem perguntas? Fórum do UiPath

Fique por dentro das novidades