Skip to content

Report a malformed config instead of panicking in pipectl migrate - #7326

Open
omlahore wants to merge 3 commits into
pipe-cd:masterfrom
omlahore:fix/migrate-panics-on-malformed-config
Open

Report a malformed config instead of panicking in pipectl migrate#7326
omlahore wants to merge 3 commits into
pipe-cd:masterfrom
omlahore:fix/migrate-panics-on-malformed-config

Conversation

@omlahore

@omlahore omlahore commented Sep 6, 2026

Copy link
Copy Markdown

What happens

pipectl migrate application-config reads a user's YAML into map[string]any and then asserts on three lookups out of it without the comma-ok, so a file with the wrong shape panics the CLI instead of being reported.

application_config.go, on 3321879:

oldSpec := cfg["spec"].(map[string]any)
for _, oldStage := range oldPipelineCfg.(map[string]any)["stages"].([]any) {
switch config.Kind(cfg["kind"].(string)) {

cfg comes straight from os.ReadFile then yaml.Unmarshal(data, &cfg) a few lines above, so every one of those lookups can hold something other than the expected type, or nothing at all.

Reproduction

Six configs a user could plausibly write, each in a file passed to migrateApplicationConfig. All six panic before this change:

--- FAIL: TestMigrateApplicationConfigMalformed/kind_missing
    panicked on a user-supplied config: interface conversion: interface {} is nil, not string
--- FAIL: TestMigrateApplicationConfigMalformed/kind_is_a_number
    panicked on a user-supplied config: interface conversion: interface {} is float64, not string
--- FAIL: TestMigrateApplicationConfigMalformed/pipeline_is_a_list
    panicked on a user-supplied config: interface conversion: interface {} is []interface {}, not map[string]interface {}
--- FAIL: TestMigrateApplicationConfigMalformed/stages_is_a_string
    panicked on a user-supplied config: interface conversion: interface {} is string, not []interface {}
--- FAIL: TestMigrateApplicationConfigMalformed/spec_is_a_string
    panicked on a user-supplied config: interface conversion: interface {} is string, not map[string]interface {}
--- FAIL: TestMigrateApplicationConfigMalformed/spec_missing
    panicked on a user-supplied config: interface conversion: interface {} is nil, not map[string]interface {}

A config file with no kind: is enough.

The change

Each of the three uses the checked form and returns an error naming the field and the type that was actually there, matching how the same function already handles stages[] and stages[].with two lines further down:

if oldStageCfg, ok := oldStage.(map[string]any); ok {
if withCfg, ok := stageCfg["with"].(map[string]any); ok {

So this is an omission rather than a different convention.

spec.pipeline.stages being absent stays valid and is not an error, only a non-list value is.

All six cases pass after the change, and go test ./pkg/app/pipectl/... is green.

migrateApplicationConfig unmarshals a user's YAML into map[string]any and then
asserts on three lookups without the comma-ok: spec, spec.pipeline.stages and
kind. Any of them holding another type, or being absent, panics the CLI with an
interface conversion instead of telling the user which field is wrong.

Six configs a user could plausibly write all panic today, including a file with
no kind at all. The same function already uses the checked form two lines
further down for stages[] and stages[].with, so this is an omission rather than
a convention.

Return an error naming the field and the type found.

Signed-off-by: Om <omlahore47@gmail.com>
@omlahore
omlahore requested a review from a team as a code owner September 6, 2026 20:03
@omlahore
omlahore requested review from armistcxy, mohammedfirdouss and t-kikuc and a lite review from Copilot September 6, 2026 20:03
@netlify

netlify Bot commented Sep 6, 2026

Copy link
Copy Markdown

Deploy Preview for pipecd-site canceled.

Name Link
🔨 Latest commit 62d4f3e
🔍 Latest deploy log https://app.netlify.com/projects/pipecd-site/deploys/6a9ec84922602100082a0710

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The newly added Go test file is missing the repository-standard Apache 2.0 license header at the top.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR improves the robustness of pipectl migrate application-config by replacing unsafe type assertions on user-supplied YAML with checked assertions that return descriptive errors, preventing CLI panics on malformed configs.

Changes:

  • Add validation for spec, spec.pipeline, spec.pipeline.stages, and kind when decoding YAML into map[string]any.
  • Return structured errors (and log them) instead of panicking on unexpected shapes/types.
  • Add regression tests ensuring malformed configs don’t panic and instead return errors.
File summaries
File Description
pkg/app/pipectl/cmd/migrate/application_config.go Replaces panic-prone type assertions with comma-ok checks and explicit errors for invalid config shapes.
pkg/app/pipectl/cmd/migrate/malformed_config_test.go Adds tests covering several malformed YAML shapes to ensure errors are returned (not panics).
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread pkg/app/pipectl/cmd/migrate/malformed_config_test.go
The default branch re-asserted cfg["kind"].(string) after the switch had
already been entered on a checked value, so the same lookup was asserted twice.
Use the string that was already validated.

Signed-off-by: Om <omlahore47@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants