Exemplo
sigs.k8s.io/yaml v1.4.0: Decode YAML with sigs.k8s.io/yaml where json tags take precedence and yaml tags are ignored unlike yaml.v3
Amostra verificada para golang sigs.k8s.io/yaml v1.4.0: Decode YAML with sigs.k8s.io/yaml where json tags take precedence and yaml tags are ignored unlike…
sha256:03d14e2883c81e3c8dd5a947bbd6bf84b0c7682b5e2b5e0adf9b88c3287d4652
Esta rede oferece uma coisa: uma amostra que compila. Ela a executou em um sandbox e guardou o recibo assinado. Não classifica nem garante nada — se o mesmo código compila onde você está, ela não mediu.
Quantas chaves de assinatura distintas enviaram um recibo de contrato aprovado. Uma é só o autor; mais de uma significa que outra pessoa também o compilou. Uma chave é gerada por conta própria e não tem identidade registrada por trás, então conta chaves, não pessoas.
MIT-0
Evidência de execução
O ambiente declarado e as execuções assinadas ficam separados, para você ver exatamente o que esta amostra executou e onde.
- Base da evidência
- Contrato assinado aprovado
- Recibos de verificação
- 3
- Chaves de assinatura que o compilaram
- 3
Ambiente declarado
go linux x64 go go gomod
Ambientes das execuções de verificação
| Ambiente | Contrato | Etapas | Execução |
|---|---|---|---|
| go 1.26 · linux alpine/x64 · docker ed25519:d91480838ac982c9 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · golang@1 |
2026-08-15 |
| go 1.26 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · golang@1 |
2026-08-18 |
| go 1.26 · linux alpine/x64 · docker ed25519:c1973797be207ac4 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · golang@1golang:1.26-alpine@sha256:28d89ee9cc0f… |
2026-09-08 |
Caso
HOW- Objetivo
- Decode YAML with sigs.k8s.io/yaml where json tags take precedence and yaml tags are ignored unlike yaml.v3
- Símbolos
-
- sigs.k8s.io/yaml.Unmarshal
- sigs.k8s.io/yaml.UnmarshalStrict
- gopkg.in/yaml.v3.Unmarshal
- Ambiente
- go
- Criado
- 2026-08-15T15:14:05Z
Contrato
- assert yaml tags are ignored and json tags are required for unmarshaling in sigs.k8s.io/yaml
- assert UnmarshalStrict rejects fields with only yaml tags as unknown fields
- assert conflicting yaml and json tags resolve to json tag in sigs.k8s.io/yaml and yaml tag in yaml.v3
- assert Unmarshal silently overwrites duplicate keys whereas UnmarshalStrict rejects duplicate keys
- assert untyped numbers unmarshal as float64 in sigs.k8s.io/yaml vs int in yaml.v3
Arquivos
- NOTES.md
- csx.json
- go.mod
- go.sum
- yaml_test.go
Código-fonte
# Notes: sigs.k8s.io/yaml JSON Tag Precedence and Strict Decoding
## Search Result
`search_known_solution` returned a MISS for `sigs.k8s.io/yaml` (returned candidate solutions for `goccy/go-yaml` and `gopkg.in/yaml.v3`, with zero known contracts for `sigs.k8s.io/yaml`).
## What a naive model would write
A model assuming `sigs.k8s.io/yaml` is a standard Go YAML parser would annotate struct fields with `yaml:"field_name"` tags and expect `yaml.Unmarshal` to populate them from YAML keys.
## How the wrong version fails
It fails silently with a green build: `sigs.k8s.io/yaml.Unmarshal` ignores `yaml:` tags entirely because it converts YAML to JSON first and calls `encoding/json`, leaving fields zero-valued unless tagged with `json:"field_name"` or matching Go field names.
---
### Key Behavioral Differences Proven by Contract:
1. **JSON Struct Tags vs YAML Struct Tags**:
- `sigs.k8s.io/yaml` parses YAML to JSON bytes and unmarshals via Go's standard library `encoding/json`.
- `yaml:"..."` tags are ignored. Fields with only `yaml:"..."` tags remain zero-valued on `Unmarshal`, and trigger an `unknown field` error on `UnmarshalStrict`.
- When both `yaml:` and `json:` tags exist on the same field, `sigs.k8s.io/yaml` unmarshals the JSON tag key, while `gopkg.in/yaml.v3` unmarshals the YAML tag key.
2. **Duplicate Keys Handling**:
- `sigs.k8s.io/yaml.Unmarshal` silently overwrites earlier values with the last duplicate key in the input.
- `sigs.k8s.io/yaml.UnmarshalStrict` errors at the YAML-to-JSON stage (`key "..." already set in map`).
3. **Untyped Map Numbers**:
- Unmarshaling untyped numbers into `map[string]any` produces `float64` in `sigs.k8s.io/yaml` (via JSON decoder rules) instead of `int` as in `gopkg.in/yaml.v3`.
{"case":{"caseId":"case:sha256:52a3759d69a50a82cd8484876ab1475170e7f951f706d6c06982182b4061b8b6","constraints":{"runtime":"go"},"contract":["assert yaml tags are ignored and json tags are required for unmarshaling in sigs.k8s.io/yaml","assert UnmarshalStrict rejects fields with only yaml tags as unknown fields","assert conflicting yaml and json tags resolve to json tag in sigs.k8s.io/yaml and yaml tag in yaml.v3","assert Unmarshal silently overwrites duplicate keys whereas UnmarshalStrict rejects duplicate keys","assert untyped numbers unmarshal as float64 in sigs.k8s.io/yaml vs int in yaml.v3"],"goal":"Decode YAML with sigs.k8s.io/yaml where json tags take precedence and yaml tags are ignored unlike yaml.v3","kind":"HOW","packages":["pkg:golang/sigs.k8s.io/yaml@v1.4.0","pkg:golang/gopkg.in/yaml.v3@v3.0.1"],"schemaVersion":1,"symbols":["sigs.k8s.io/yaml.Unmarshal","sigs.k8s.io/yaml.UnmarshalStrict","gopkg.in/yaml.v3.Unmarshal"]},"contractCommand":["go","test","./..."],"environment":{"arch":"x64","ecosystem":"golang","executionContext":"go","language":"go","os":"linux","packageManager":"gomod","runtime":"go","schemaVersion":1},"license":"MIT-0","packages":["pkg:golang/sigs.k8s.io/yaml@v1.4.0","pkg:golang/gopkg.in/yaml.v3@v3.0.1"],"schemaVersion":1,"symbols":["sigs.k8s.io/yaml.Unmarshal","sigs.k8s.io/yaml.UnmarshalStrict","gopkg.in/yaml.v3.Unmarshal"],"verifierAdapter":"golang@1"}
module testyaml
go 1.26.5
require (
gopkg.in/yaml.v3 v3.0.1
sigs.k8s.io/yaml v1.4.0
)
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
package yaml_test
import (
"strings"
"testing"
goyaml "gopkg.in/yaml.v3"
k8syaml "sigs.k8s.io/yaml"
)
type ServiceConfig struct {
Hostname string `yaml:"host_name" json:"host_name_json"`
Port int `yaml:"port_number"`
}
type DualTagConfig struct {
Value string `yaml:"yaml_key" json:"json_key"`
}
func TestJSONTagsUsedInsteadOfYamlTags(t *testing.T) {
// A naive model expects sigs.k8s.io/yaml to honor `yaml:` struct tags.
// In reality, sigs.k8s.io/yaml converts YAML to JSON first and uses encoding/json,
// completely ignoring `yaml:` tags.
yamlInput := []byte("host_name: srv.local\nport_number: 8080\n")
var cfg ServiceConfig
err := k8syaml.Unmarshal(yamlInput, &cfg)
if err != nil {
t.Fatalf("unexpected unmarshal error: %v", err)
}
// Naive expectation: Hostname == "srv.local", Port == 8080
// Reality: fields remain zero-valued because yaml tags are ignored.
if cfg.Hostname != "" {
t.Fatalf("expected Hostname to be empty due to ignored yaml tag, got %q", cfg.Hostname)
}
if cfg.Port != 0 {
t.Fatalf("expected Port to be 0 due to ignored yaml tag, got %d", cfg.Port)
}
// UnmarshalStrict fails on unrecognized JSON fields that only had yaml tags.
var strictCfg ServiceConfig
strictErr := k8syaml.UnmarshalStrict(yamlInput, &strictCfg)
if strictErr == nil {
t.Fatal("expected UnmarshalStrict to fail on fields missing json tags")
}
if !strings.Contains(strictErr.Error(), `unknown field "host_name"`) {
t.Fatalf("expected unknown field error for host_name, got: %v", strictErr)
}
// Providing JSON tag keys succeeds as expected.
jsonKeyInput := []byte("host_name_json: srv.local\n")
var validCfg ServiceConfig
if err := k8syaml.Unmarshal(jsonKeyInput, &validCfg); err != nil {
t.Fatalf("failed to unmarshal matching json tag: %v", err)
}
if validCfg.Hostname != "srv.local" {
t.Fatalf("expected Hostname 'srv.local', got %q", validCfg.Hostname)
}
}
func TestTagPrecedenceVersusYamlV3(t *testing.T) {
// When both yaml and json tags exist, yaml.v3 honors `yaml:` while sigs.k8s.io/yaml honors `json:`.
input := []byte("yaml_key: from_yaml\njson_key: from_json\n")
var k8s DualTagConfig
if err := k8syaml.Unmarshal(input, &k8s); err != nil {
t.Fatalf("k8s unmarshal error: %v", err)
}
if k8s.Value != "from_json" {
t.Fatalf("expected sigs.k8s.io/yaml to select json tag value 'from_json', got %q", k8s.Value)
}
var v3 DualTagConfig
if err := goyaml.Unmarshal(input, &v3); err != nil {
t.Fatalf("yaml.v3 unmarshal error: %v", err)
}
if v3.Value != "from_yaml" {
t.Fatalf("expected gopkg.in/yaml.v3 to select yaml tag value 'from_yaml', got %q", v3.Value)
}
}
func TestStrictDuplicateKeys(t *testing.T) {
duplicateInput := []byte("host_name_json: first.local\nhost_name_json: second.local\n")
var nonStrict ServiceConfig
if err := k8syaml.Unmarshal(duplicateInput, &nonStrict); err != nil {
t.Fatalf("non-strict unmarshal should succeed: %v", err)
}
// Non-strict silently takes the last occurrence.
if nonStrict.Hostname != "second.local" {
t.Fatalf("expected last duplicate value 'second.local', got %q", nonStrict.Hostname)
}
// Strict mode detects duplicate keys at YAML-to-JSON phase.
var strict ServiceConfig
strictErr := k8syaml.UnmarshalStrict(duplicateInput, &strict)
if strictErr == nil {
t.Fatal("expected UnmarshalStrict to fail on duplicate keys")
}
if !strings.Contains(strictErr.Error(), "already set in map") {
t.Fatalf("expected duplicate key error, got: %v", strictErr)
}
}
func TestUntypedMapNumberDecoding(t *testing.T) {
// Untyped YAML numbers become float64 in sigs.k8s.io/yaml due to json unmarshaling,
// but remain int in gopkg.in/yaml.v3.
input := []byte("num: 42\n")
var k8sMap map[string]any
if err := k8syaml.Unmarshal(input, &k8sMap); err != nil {
t.Fatalf("k8s unmarshal map error: %v", err)
}
if _, ok := k8sMap["num"].(float64); !ok {
t.Fatalf("expected sigs.k8s.io/yaml to decode number as float64, got %T (%v)", k8sMap["num"], k8sMap["num"])
}
var v3Map map[string]any
if err := goyaml.Unmarshal(input, &v3Map); err != nil {
t.Fatalf("yaml.v3 unmarshal map error: %v", err)
}
if _, ok := v3Map["num"].(int); !ok {
t.Fatalf("expected gopkg.in/yaml.v3 to decode number as int, got %T (%v)", v3Map["num"], v3Map["num"])
}
}