{"record":{"id":"be478cac53cf488b","repo":"FiloSottile/age","slug":"repeated-labels-stanza","errorCode":null,"errorMessage":"repeated labels stanza","messagePattern":"repeated labels stanza","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/client.go","lineNumber":139,"sourceCode":"\t\t\t\treturn nil, nil, fmt.Errorf(\"malformed recipient stanza: invalid index\")\n\t\t\t}\n\t\t\t// We only send a single file key, so the index must be 0.\n\t\t\tif n != 0 {\n\t\t\t\treturn nil, nil, fmt.Errorf(\"malformed recipient stanza: unexpected index\")\n\t\t\t}\n\n\t\t\tstanzas = append(stanzas, &age.Stanza{\n\t\t\t\tType: s.Args[1],\n\t\t\t\tArgs: s.Args[2:],\n\t\t\t\tBody: s.Body,\n\t\t\t})\n\n\t\t\tif err := writeStanza(conn, \"ok\"); err != nil {\n\t\t\t\treturn nil, nil, err\n\t\t\t}\n\t\tcase \"labels\":\n\t\t\tif labels != nil {\n\t\t\t\treturn nil, nil, fmt.Errorf(\"repeated labels stanza\")\n\t\t\t}\n\t\t\tlabels = s.Args\n\n\t\t\tif err := writeStanza(conn, \"ok\"); err != nil {\n\t\t\t\treturn nil, nil, err\n\t\t\t}\n\t\tcase \"error\":\n\t\t\tif err := writeStanza(conn, \"ok\"); err != nil {\n\t\t\t\treturn nil, nil, err\n\t\t\t}\n\n\t\t\treturn nil, nil, fmt.Errorf(\"%s\", s.Body)\n\t\tcase \"done\":\n\t\t\tbreak ReadLoop\n\t\tdefault:\n\t\t\tif ok, err := r.ui.handle(r.name, conn, s); err != nil {\n\t\t\t\treturn nil, nil, err\n\t\t\t} else if !ok {","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/FiloSottile/age/blob/b74dce4cdbe35b5e5f66c06d9612b72f89028758/plugin/client.go#L121-L157","documentation":"The plugin sent more than one 'labels' stanza during the wrap protocol. A plugin must emit at most one labels stanza describing its supported labels, so a second one is a protocol violation and the client aborts.","triggerScenarios":"Calling WrapWithLabels/Wrap with a plugin that sends duplicate 'labels' stanzas in response to the file key, e.g. a buggy plugin loop that emits labels once per stanza instead of once per session.","commonSituations":"Developing a custom plugin and emitting labels inside a per-stanza loop; a plugin version bug where labels are re-sent after an 'ok'; misbehaving third-party plugins.","solutions":["If you develop the plugin, emit the labels stanza exactly once, outside any per-stanza loop.","Upgrade the plugin to the latest version where the duplicate-labels bug is fixed.","Capture the plugin transcript to confirm which code path sends labels twice.","Report the bug to the plugin maintainer if it is not your code."],"exampleFix":"// before (plugin side, buggy)\nfor _, st := range stanzas {\n    writeStanza(conn, \"recipient-stanza\", \"0\", st.Type, st.Args...)\n    writeStanza(conn, \"labels\", \"post-quantum\") // emitted each iteration\n}\n// after\nfor _, st := range stanzas {\n    writeStanza(conn, \"recipient-stanza\", \"0\", st.Type, st.Args...)\n}\nwriteStanza(conn, \"labels\", \"post-quantum\") // once","handlingStrategy":"validation","validationCode":"// Go (plugin side): emit labels exactly once\ntype labelsWriter struct{ sent bool }\nfunc (w *labelsWriter) writeLabels(conn io.Writer, labels ...string) error {\n    if w.sent { return fmt.Errorf(\"labels already sent\") }\n    w.sent = true\n    return writeStanza(conn, \"labels\", labels...)\n}","typeGuard":null,"tryCatchPattern":"if err != nil {\n    if strings.Contains(err.Error(), \"repeated labels stanza\") {\n        return fmt.Errorf(\"plugin bug: duplicate labels stanza; upgrade plugin: %w\", err)\n    }\n    return err\n}","preventionTips":["Emit the labels stanza once per session, outside any per-stanza loop.","Track a 'labels sent' flag in plugin code.","Test plugins end-to-end against the reference age client.","Upgrade plugins that predate the labels protocol rules."],"tags":["go","age","plugin","protocol","duplicate"],"backgroundTag":"plugin-protocol-violation","analyzedSha":"b74dce4cdbe35b5e5f66c06d9612b72f89028758","analyzedAt":"2026-08-31T23:59:31.627Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}