Skip to main content
For the complete documentation index for agents and LLMs, see llms.txt.

The io-config File

When you deploy or validate a pipeline, the SDK needs to know which of your pipeline's sockets receive the user's query and which return the results. By default, it works this out from your socket names. When the default names don't fit your pipeline, or when you want stable, repeatable builds, you can lock the mapping in a YAML file placed next to your pipeline.


Automatic Mapping

If you use conventional input and output socket names, the SDK infers the mapping automatically. If your pipeline uses any of the following socket names, inference works without a file.

Input sockets (any mandatory input using these names maps automatically):

Socket NamePlatform Input
query or questionquery — the user's text, sent by the Playground and chat UI
filtersfilters — metadata filters that narrow retrieval
files or sourcesfiles — files uploaded alongside the query
messagesmessages — chat history as ChatMessage objects

Output sockets (first match per platform key wins):

Socket NamePlatform Output
answersanswers — generated or extracted answers shown as the reply
documentsdocuments — retrieved documents shown as sources
replies or messagesmessages — assistant chat messages

If every mandatory input and at least one output map automatically, deploy and validate run without stopping to ask anything.

You don't need the io-config file if your pipeline uses conventional input and output socket names.

When You Need a Config File

Use a config file when:

  • Your socket names don't match the list above. A mandatory socket with a custom name won't be mapped, and the deployed pipeline will fail at query time with "Missing mandatory input".
  • You run in CI or another non-interactive environment. When a socket can't be inferred, the CLI stops and prompts you to pick one. A saved config file skips the prompt.
  • You want a stable, version-controlled mapping. Inference can change when you rename or add sockets. A config file locks the mapping so a refactor doesn't silently change which socket receives the query.
  • You need pipeline-level settings, such as session_storage, pipeline_output_type, or dependencies.

File Location

Name the file <pipeline>.io.yaml and place it in the same folder as your pipeline file. The SDK picks it up automatically and tells you it's doing so:

Using I/O mapping from pipeline.io.yaml (pass --io-config to override, or delete the file to re-map).

To use a file with a different name or location, pass --io-config <path> explicitly. An explicit --io-config always wins over the auto-detected file.

Generating the File Automatically

To generate the configuration file, run deploy --share. When --share is set, the CLI shows you the inferred mapping and asks you to confirm it. At the end it asks:

Save this mapping to pipeline.io.yaml so future deploys use it automatically? [Y/n]:

If you say yes, it writes a fully commented pipeline.io.yaml next to your pipeline file. Edit it freely, or delete it to go back to the interactive prompt.

File Contents

The file accepts two kinds of content: the socket mapping (inputs: and outputs:) and pipeline settings. Both are optional — you can use the file for just the mapping, just the settings, or both.

The Socket Mapping

inputs: maps each platform input key to one or more component.socket paths in your pipeline. An input can fan out to several sockets.

outputs: maps each platform output key to exactly one component.socket path.

inputs:
query:
- retriever.query
- reranker.query # fan out to two sockets
filters:
- retriever.filters
outputs:
answers: answer_builder.answers

The platform input keys are query, filters, files, and messages. The platform output keys are answers, documents, and messages. You only need to list the keys your pipeline uses.

Pipeline Settings

KeyWhat it doesDefault when absent
pipeline_output_type:How the Playground renders results: generative, chat, extractive, or document.Inferred from the pipeline shape.
session_storage:true gives the pipeline a per-session workspace. Files a tool writes stay available for the next run in the same session.Off.
async_enabled:true runs the pipeline with Pipeline.run_async, so independent branches run in parallel. Only accepted when a dependencies: pin includes haystack-ai==3.0 or later.Off, or read from the pipeline class for Haystack 2.x (AsyncPipeline).
dependencies:pip packages the deployed revision installs. Replaces the automatic haystack-ai pin — include it yourself if you still want it. [] ships no pins.The haystack-ai version used by the interpreter that loaded your pipeline.

async_enabled

Haystack 2.x expressed async execution through the AsyncPipeline class, which the SDK reads automatically. Haystack 3.0 merged that class into Pipeline, so inference no longer works. The async_enabled key fills that gap, but only under a 3.x pin — having both the class signal (2.x) and the key would create two competing sources of truth.

If you're on Haystack 3.x and want async execution, pin the version and set the key:

async_enabled: true
dependencies:
- haystack-ai==3.0.0

Full Example

# pipeline.io.yaml
inputs:
query:
- retriever.query
filters:
- retriever.filters
outputs:
answers: answer_builder.answers
pipeline_output_type: generative
session_storage: true
async_enabled: true # accepted because the 3.x pin is below
dependencies:
- haystack-ai==3.0.0
- my-private-lib==1.4

Things to Watch Out For

Unknown keys—purpose

Any top-level key the SDK doesn't recognize is passed straight through to the deployed pipeline config, with a note. This is intentional. It lets you set a platform config key that's newer than your installed SDK without waiting for an SDK update. But it means typos pass through too. session_storge: true won't raise an error; it will just show up in the deployed config with no effect. Read the note carefully.

run Ignores Pipeline Settings

run uses the inputs: and outputs: sections and ignores the pipeline settings. Settings like session_storage, pipeline_output_type, and dependencies describe a deployed revision. The sandbox has no search session, installs nothing, and renders no Playground result, so those settings don't apply. async_enabled is the exception — it changes how the graph executes, which a sandbox run does too.