Kubeflow Pipelines v2: Why Typed Artifacts Fail at Runtime, Not Compile Time
Typed artifact passing in Kubeflow Pipelines v2 is a runtime contract, not a compile-time check. Learn how OutputPath and InputPath resolve against cluster storage, and how to verify your pipeline setup before it fails.
23 Nov 2025, 06:13 UTC

You wire two components together: one writes a Dataset, the next reads it. The pipeline compiles cleanly, you upload it to the Kubeflow dashboard, and the run fails—or worse, the downstream step receives an empty directory. The problem is rarely the Python logic. In Kubeflow Pipelines (KFP) SDK v2, typed artifact passing is a runtime contract between your component signatures and the cluster's object storage, not a compile-time guarantee. If that contract is misconfigured, the compiler will not warn you.
Takeaway: Before debugging your component code, verify that the SDK version, artifact type names, and storage configuration line up across the compile step and the cluster.
How v2 typed artifacts actually move
When you decorate a function with @component, the KFP SDK v2 compiler translates it into an Intermediate Representation (IR) YAML that the Argo Workflows-based runtime understands. If you annotate an output with OutputPath('Dataset'), the compiler does not embed a real storage path in the YAML. Instead, it emits a placeholder that tells the KFP operator to expect a local file written by your container.
At runtime, your component writes to that temporary path inside the pod. The KFP operator then uploads the file to the pipeline artifact store—typically MinIO in a standard installation. Downstream, a parameter annotated with InputPath('Dataset') is resolved by the SDK to the artifact URI at execution time. If ML Metadata (MLMD) is configured, the operator also records the artifact name, URI, and data format for lineage tracking.
The important boundary is this: the compiler validates that your Python is well-formed, but it does not guarantee that the storage bucket is reachable, that credentials are valid, or that the type strings match across every SDK version.
A minimal producer-consumer pattern
The following example shows the core contract. Run it in a Python environment where kfp is installed.
from kfp.dsl import component, InputPath, OutputPath
@component
def produce_dataset(output_path: OutputPath('Dataset')):
with open(output_path, 'w') as f:
f.write('id,value\n1,42\n')
@component
def consume_dataset(input_path: InputPath('Dataset')):
with open(input_path) as f:
print(f.read())
To compile this into a pipeline definition, use the v2 compiler API:
# Run in your local Python environment or notebook with kfp installed
from kfp.compiler import Compiler
from kfp import dsl
@dsl.pipeline(name='artifact-demo')
def demo_pipeline():
produce = produce_dataset()
consume_dataset(produce.outputs['output_path'])
Compiler().compile(demo_pipeline, 'pipeline.yaml')
After compilation, open pipeline.yaml and look for inputPath and outputPath entries. They should contain templated placeholders, not absolute local paths from your authoring machine. If you see hardcoded paths, the component was likely authored with a v1-style API or an incompatible SDK version.
Where the contract breaks
Version drift between SDK and cluster. KFP SDK v1 and v2 use different decorators and compilation APIs. Mixing them can produce invalid pipeline YAML that the Argo runtime rejects. Before authoring, check the installed SDK version with pip show kfp in your local environment and compare it against the version shown in your cluster's KFP dashboard. Recent SDK releases may expose features that older cluster installations do not support.
Object storage reachability. Typed artifact passing requires the object storage bucket to be reachable from every workflow pod. Missing credentials or restrictive network policies can cause step failures without obvious error messages, because the upload or download fails inside the operator or the sidecar rather than in your component code.
Type name mismatches. The strings 'Dataset' and 'Model' must match between producer and consumer. In some SDK versions, a mismatch may not be caught at compile time; the pipeline will deploy and then fail at runtime when the operator cannot resolve the expected artifact type.
A practical verification checklist
- Check versions. Run
pip show kfplocally (no cluster permissions required) and confirm it aligns with the KFP dashboard version on your cluster. - Compile and inspect. Build a minimal two-step pipeline locally with
kfp.compiler.Compiler().compile(...)and inspect the generated YAML forinputPathandoutputPathplaceholders. This is a local operation and does not touch the cluster. - Confirm storage configuration. Verify that the artifact storage secret and bucket endpoint match the KFP installation's
kfp-profile-controllerconfiguration. This requires read access to the cluster's KFP installation settings. - Run and trace. Execute the pipeline on a test cluster (requires permissions to create and monitor workflow runs) and verify artifact lineage in the KFP UI or ML Metadata database for both the producing and consuming steps.
Actionable closing
Treat typed artifacts as a cluster integration point, not just a function signature. The compiler gives you a placeholder; the operator gives you the file. When a pipeline fails, check the runtime boundary first—storage reachability, type strings, and SDK-cluster version alignment—before you rewrite your component logic.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.