{"record":{"id":"31f7677feb09ac87","repo":"FiloSottile/age","slug":"malformed-recipient-q-invalid-type-q","errorCode":null,"errorMessage":"malformed recipient %q: invalid type %q","messagePattern":"malformed recipient %q: invalid type %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tag/tag.go","lineNumber":62,"sourceCode":"\tt, k, err := plugin.ParseRecipient(s)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"malformed recipient %q: %v\", s, err)\n\t}\n\tswitch t {\n\tcase \"tag\":\n\t\tr, err := NewClassicRecipient(k)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"malformed recipient %q: %v\", s, err)\n\t\t}\n\t\treturn r, nil\n\tcase \"tagpq\":\n\t\tr, err := NewHybridRecipient(k)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"malformed recipient %q: %v\", s, err)\n\t\t}\n\t\treturn r, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"malformed recipient %q: invalid type %q\", s, t)\n\t}\n}\n\nconst compressedPointSize = 1 + 32\nconst uncompressedPointSize = 1 + 32 + 32\n\n// NewClassicRecipient returns a new P-256 [Recipient] from a raw public key.\nfunc NewClassicRecipient(publicKey []byte) (*Recipient, error) {\n\tif len(publicKey) != compressedPointSize {\n\t\treturn nil, fmt.Errorf(\"invalid tag recipient public key size %d\", len(publicKey))\n\t}\n\tp, err := nistec.NewP256Point().SetBytes(publicKey)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid tag recipient public key: %v\", err)\n\t}\n\tk, err := hpke.DHKEM(ecdh.P256()).NewPublicKey(p.Bytes())\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid tag recipient public key: %v\", err)","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/FiloSottile/age/blob/b74dce4cdbe35b5e5f66c06d9612b72f89028758/tag/tag.go#L44-L80","documentation":"tag.ParseRecipient decodes the Bech32 string into a plugin type t (\"tag\" or \"tagpq\"). If the decoded type is neither, this error reports the unexpected type. It means the string parsed as a valid plugin recipient but for a different recipient type than this library supports.","triggerScenarios":"Calling tag.ParseRecipient with a valid plugin.Bech32 recipient string whose inner type is not \"tag\" or \"tagpq\" — e.g. an X25519 \"age1...\" key or another plugin's recipient.","commonSituations":"Passing a standard age X25519 recipient to tag.ParseRecipient; passing recipients from other age plugins; typos in the recipient prefix that still decode as a valid but different type.","solutions":["Check the reported %q type to identify what kind of recipient you actually passed.","Use plugin.Parse recipients (e.g. age.ParseRecipient) for standard X25519 age1... keys instead of tag.ParseRecipient.","Ensure you have the correct tag recipient string for this library (age1tag1 / age1tagpq1).","If you need both, dispatch on the parsed type before choosing the constructor."],"exampleFix":"// before\nr, err := tag.ParseRecipient(\"age1qq...\") // X25519 recipient\n// after\nif strings.HasPrefix(s, \"age1tag1\") || strings.HasPrefix(s, \"age1tagpq1\") {\n    r, err = tag.ParseRecipient(s)\n} else {\n    r, err = age.ParseRecipients(...) // handle standard age keys separately\n}","handlingStrategy":"validation","validationCode":"s := strings.TrimSpace(userInput)\nswitch {\ncase strings.HasPrefix(s, \"age1tag1\"), strings.HasPrefix(s, \"age1tagpq1\"):\n    r, err = tag.ParseRecipient(s)\ndefault:\n    return fmt.Errorf(\"unsupported recipient type, expected age1tag1/age1tagpq1\")\n}","typeGuard":"func isTagRecipient(s string) bool {\n    return strings.HasPrefix(s, \"age1tag1\") || strings.HasPrefix(s, \"age1tagpq1\")\n}","tryCatchPattern":null,"preventionTips":["Dispatch on the recipient prefix before choosing a parser.","Use age.ParseRecipients for standard X25519 keys, tag.ParseRecipient only for tag keys.","Never assume all age1... strings are interchangeable."],"tags":["go","parsing","recipient","type-mismatch"],"backgroundTag":"unsupported-recipient-type","analyzedSha":"b74dce4cdbe35b5e5f66c06d9612b72f89028758","analyzedAt":"2026-08-31T23:59:31.627Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}