docker/compose · error
cannot render project into yaml: %w
Error message
cannot render project into yaml: %w
What it means
In the compose-to-Podman-bridge converter (bridge.Convert), the project is serialized back to YAML (project.MarshalYAML with types.WithSecretContent) so transformers can operate on compose-style attribute names. This error means that serialization itself failed. The %w wraps the underlying marshal error, which almost always indicates data in the in-memory project that cannot be represented in the compose YAML schema.
Source
Thrown at pkg/bridge/convert.go:64
Output string
Templates string
Transformations []string
}
func Convert(ctx context.Context, dockerCli command.Cli, project *types.Project, opts ConvertOptions) error {
if len(opts.Transformations) == 0 {
opts.Transformations = []string{DefaultTransformerImage}
}
// Load image references, secrets and configs, also expose ports
project, err := LoadAdditionalResources(ctx, dockerCli, project)
if err != nil {
return err
}
// for user to rely on compose.yaml attribute names, not go struct ones, we marshall back into YAML
raw, err := project.MarshalYAML(types.WithSecretContent)
// Marshall to YAML
if err != nil {
return fmt.Errorf("cannot render project into yaml: %w", err)
}
var model map[string]any
err = yaml.Unmarshal(raw, &model)
if err != nil {
return fmt.Errorf("cannot render project into yaml: %w", err)
}
if opts.Output != "" {
_ = os.RemoveAll(opts.Output)
err := os.MkdirAll(opts.Output, 0o744)
if err != nil && !os.IsExist(err) {
return fmt.Errorf("cannot create output folder: %w", err)
}
}
// Run Transformers images
return convert(ctx, dockerCli, model, opts)
}
View on GitHub (pinned to ddc4b044b6)
Solutions
- Inspect the wrapped error (%w) to identify which field failed to marshal
- Reproduce with docker compose config on the same file to see whether the CLI itself rejects the model
- Upgrade docker/compose and compose-go to matching versions so model structs and YAML schema agree
- Simplify the project (remove the suspicious service/field) and re-add pieces until the failing attribute is isolated
Defensive patterns
Strategy: try-catch
Try / catch
if err := bridge.Convert(ctx, dockerCli, project, opts); err != nil {
if strings.Contains(err.Error(), "cannot render project into yaml") {
// inspect project for non-serializable fields; fall back to a file-loaded project
log.Printf("conversion input invalid: %v", errors.Unwrap(err))
}
return err
} Prevention
- Prefer loading projects from compose files via the standard loader rather than building them by hand
- Keep compose-go model structs and yaml library versions aligned with the compose release you call
- Round-trip test: MarshalYAML then Unmarshal any programmatically built project before passing it to the bridge
When it happens
Trigger: Calling bridge.Convert with a programmatically built *types.Project containing values that do not survive marshal/unmarshal (custom types, invalid map keys, unsupported fields); a project mutated by LoadAdditionalResources into a state the YAML schema rejects.
Common situations: Using the bridge converter (docker compose-to-podman style flows) on a project with unusual or manually constructed fields; version mismatches between compose-go model structs and the YAML schema; injecting non-serializable content into service maps before conversion.
Related errors
- cannot create output folder: %w
- healthcheck.start_interval requires healthcheck.start_period
- output folder %s already exists
- cannot create output folder: %w
- saving creds for API socket: %w
AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15).
Data as JSON: /api/errors/bab542ab70354c57.
Report an issue: GitHub.