Skip to content

fix(backend): reserve the root component name and name the task in compiler lookup errors. Part of #13966 - #15275

Open
jsonmp-k8 wants to merge 2 commits into
kubeflow:masterfrom
jsonmp-k8:fix/compiler-reserve-root-component
Open

jsonmp-k8 wants to merge 2 commits into
kubeflow:masterfrom
jsonmp-k8:fix/compiler-reserve-root-component

Conversation

@jsonmp-k8

Copy link
Copy Markdown
Contributor

Problem

Two more items from #13966, following #15268 (circular references):

  1. root is not reserved. The compiler visits the pipeline's root DAG under the name root (RootComponentName), but nothing stops a user component from having the same name (TODO(Bobgy): reserve root as a keyword). Referencing such a component is reported as a circular reference, root -> root, which points at the wrong problem. An unreferenced root component is accepted silently.
  2. Lookup errors don't say where the reference is. When a task references an undefined component, or a component names an undefined executor, the error only names the component being processed: error processing component name="comp-a": cannot find component ref name="comp-missing". The task holding the broken reference isn't mentioned.

The remaining #13966 item, removing the JSON round trip in GetPipelineSpec/GetDeploymentConfig, is not included.

Part of #13966

Description of your changes:

  • Accept rejects a pipeline spec whose components contain root: component name "root" is reserved for the pipeline's root DAG. Rename the component. The SDK names components comp-<name>, so compiled SDK pipelines are unaffected. All 315 compiler golden specs pass unchanged.
  • A missing component ref now reports the task: task "task-comp-missing" references component "comp-missing", which is not defined in the pipeline spec's components. Add the component or fix the task's componentRef.
  • A missing executor now reports the task and its enclosing component: executor(label="exec-missing") not found in deployment config, used by task "task-comp-leaf" in component "comp-a". Add the executor to deploymentSpec.executors or fix the component's executorLabel. If the root itself is an executor component (a malformed spec with no enclosing task), the usage clause is omitted instead of indexing past the path.

Reproducer

A spec with root.dag.tasks.task-root.componentRef.name: root and a components.root container component:

  • Before: circular component reference detected: root -> root. Remove the task that references an enclosing component
  • After: component name "root" is reserved for the pipeline's root DAG. Rename the component
flowchart LR
  subgraph Before
    B_spec["components: {root: ...}"] --> B_dfs["DFS visits root DAG as 'root'"]
    B_dfs --> B_err["'circular reference: root -> root'<br/>or accepted if unreferenced"]
  end
  subgraph After
    A_spec["components: {root: ...}"] --> A_check["Accept checks reserved name"]
    A_check --> A_err["'component name &quot;root&quot; is reserved'"]
  end
Loading

Regression tests

In backend/src/v2/compiler/visitor_test.go:

  • TestAccept_RejectsComponentNamedRoot: referenced from the root DAG, referenced from a nested DAG, not referenced
  • TestAccept_MissingReferencesNameTheTask: undefined component, undefined executor, undefined executor on the root

Command:

go test ./backend/src/v2/compiler/ -run 'TestAccept_RejectsComponentNamedRoot|TestAccept_MissingReferencesNameTheTask' -count=1 -v

Before the fix:

Error: "circular component reference detected: root -> root. Remove the task that references an enclosing component" does not contain "component name \"root\" is reserved"
Error: "circular component reference detected: root -> comp-a -> root. Remove the task that references an enclosing component" does not contain "component name \"root\" is reserved"
Error: An error is expected but got nil.
--- FAIL: TestAccept_RejectsComponentNamedRoot (0.00s)
    --- FAIL: TestAccept_RejectsComponentNamedRoot/referenced_from_the_root_DAG (0.00s)
    --- FAIL: TestAccept_RejectsComponentNamedRoot/referenced_from_a_nested_DAG (0.00s)
    --- FAIL: TestAccept_RejectsComponentNamedRoot/not_referenced (0.00s)
Error: "error processing component name=\"comp-a\": cannot find component ref name=\"comp-missing\"" does not contain "task \"task-comp-missing\" references component \"comp-missing\""
Error: "error processing component name=\"comp-leaf\": executor(label=\"exec-missing\") not found in deployment config" does not contain "used by task \"task-comp-leaf\" in component \"comp-a\""
--- FAIL: TestAccept_MissingReferencesNameTheTask (0.00s)
    --- FAIL: TestAccept_MissingReferencesNameTheTask/undefined_component (0.00s)
    --- FAIL: TestAccept_MissingReferencesNameTheTask/undefined_executor (0.00s)
FAIL

(The undefined executor on the root case was added with the fix to cover the guard.)

After the fix:

--- PASS: TestAccept_RejectsComponentNamedRoot (0.00s)
    --- PASS: TestAccept_RejectsComponentNamedRoot/referenced_from_the_root_DAG (0.00s)
    --- PASS: TestAccept_RejectsComponentNamedRoot/referenced_from_a_nested_DAG (0.00s)
    --- PASS: TestAccept_RejectsComponentNamedRoot/not_referenced (0.00s)
--- PASS: TestAccept_MissingReferencesNameTheTask (0.00s)
    --- PASS: TestAccept_MissingReferencesNameTheTask/undefined_component (0.00s)
    --- PASS: TestAccept_MissingReferencesNameTheTask/undefined_executor (0.00s)
    --- PASS: TestAccept_MissingReferencesNameTheTask/undefined_executor_on_the_root (0.00s)
ok  	github.com/kubeflow/pipelines/backend/src/v2/compiler

Also run locally:

  • go test ./backend/src/v2/compiler/... ./backend/src/apiserver/template/...: pass
  • ginkgo ./backend/test/compiler -- -createGoldenFiles=false: 315 passed, 0 failed, 4 skipped (no golden changes)
  • golangci-lint run --new-from-rev upstream/master ./backend/src/v2/compiler/... (v2.15.0): 0 issues

Release notes / user impact:

Pipeline specs that define a component named root are rejected with an error saying the name is reserved. SDK-compiled pipelines never use that name. Errors for undefined component refs and executors now name the task holding the reference.

Checklist:

🤖 Generated with Claude Code

@google-oss-prow

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign alyssacgoins for approval. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@github-actions

github-actions Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Contributor Report for @jsonmp-k8

Metric Value
Kubeflow org member Yes
Issues opened in kubeflow/pipelines 71
Merged PRs in kubeflow/pipelines 54
GitHub account age 2838 days (created 2019-01-23)
PR comments in kubeflow/pipelines 166

@github-actions github-actions Bot added the ci-passed All CI tests on a pull request have passed label Oct 30, 2026
@jsonmp-k8

Copy link
Copy Markdown
Contributor Author

/ok-to-tws

@jsonmp-k8

Copy link
Copy Markdown
Contributor Author

/ok-to-test

@github-actions github-actions Bot added ci-passed All CI tests on a pull request have passed and removed ci-passed All CI tests on a pull request have passed labels Oct 31, 2026
@github-actions github-actions Bot removed the ci-passed All CI tests on a pull request have passed label Oct 31, 2026
@jsonmp-k8

Copy link
Copy Markdown
Contributor Author

/ok-to-test

@github-actions github-actions Bot added the ci-passed All CI tests on a pull request have passed label Oct 31, 2026
Comment thread backend/src/v2/compiler/visitor.go Resolved
@google-oss-prow google-oss-prow Bot added size/L and removed size/M labels Oct 31, 2026
@github-actions github-actions Bot added ci-passed All CI tests on a pull request have passed and removed ci-passed All CI tests on a pull request have passed labels Oct 31, 2026
…mpiler lookup errors. Part of kubeflow#13966

The v2 compiler visits the pipeline's root DAG under the name "root",
but a user component could also be called "root". Referencing it was
then reported as a circular reference ("root -> root"), and an
unreferenced one was accepted. Reject the name up front with an error
that says it is reserved.

When a task referenced an undefined component, or a component named an
undefined executor, the error only gave the component being processed.
Include the task name, and for a missing executor the component that
contains the task, so the broken reference can be found in the spec.

Signed-off-by: Jaison Paul <paul.jaison@gmail.com>
TaskInfo.name is a display label that can be empty or differ from the
task's key in the DAG's tasks map, so errors could read `task ""`. Name
the task by its key, which locates it in the spec, and add the display
name when it differs. Applies to undefined component refs, empty
component refs and undefined executors.

Signed-off-by: Jaison Paul <paul.jaison@gmail.com>
@jsonmp-k8
jsonmp-k8 force-pushed the fix/compiler-reserve-root-component branch from bab7138 to bbde079 Compare October 31, 2026 23:39
@github-actions github-actions Bot added ci-passed All CI tests on a pull request have passed and removed ci-passed All CI tests on a pull request have passed labels Oct 31, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants