{"record":{"id":"a7223d97236397b7","repo":"FiloSottile/age","slug":"malformed-file-key-stanza-invalid-index","errorCode":null,"errorMessage":"malformed file-key stanza: invalid index","messagePattern":"malformed file-key stanza: invalid index","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/client.go","lineNumber":274,"sourceCode":"\t}\n\n\t// Phase 2: plugin responds with various commands and a file key\n\tsr := format.NewStanzaReader(bufio.NewReader(conn))\nReadLoop:\n\tfor {\n\t\ts, err := i.ui.readStanza(i.name, sr)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tswitch s.Type {\n\t\tcase \"file-key\":\n\t\t\tif len(s.Args) != 1 {\n\t\t\t\treturn nil, fmt.Errorf(\"malformed file-key stanza: unexpected arguments count\")\n\t\t\t}\n\t\t\tn, err := strconv.Atoi(s.Args[0])\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"malformed file-key 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, fmt.Errorf(\"malformed file-key stanza: unexpected index\")\n\t\t\t}\n\t\t\tif fileKey != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"received duplicated file-key stanza\")\n\t\t\t}\n\n\t\t\tfileKey = s.Body\n\n\t\t\tif err := writeStanza(conn, \"ok\"); err != nil {\n\t\t\t\treturn 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, err\n\t\t\t}","sourceCodeStart":256,"sourceCodeEnd":292,"githubUrl":"https://github.com/FiloSottile/age/blob/b74dce4cdbe35b5e5f66c06d9612b72f89028758/plugin/client.go#L256-L292","documentation":"The client received a file-key stanza whose single argument could not be parsed as an integer index (strconv.Atoi failed). The plugin protocol requires the argument to be a decimal file index, so non-numeric content is rejected as malformed.","triggerScenarios":"A plugin sends \"file-key\" with an argument that is not a decimal number (e.g. empty string, \"abc\", hex \"0x0\", whitespace-padded value) during Unwrap.","commonSituations":"Plugin implementations that format the index incorrectly (e.g. via fmt.Sprintf with %v on a non-int, or concatenating labels into the argument); corrupted or truncated pipe output from a failing plugin process.","solutions":["Update/fix the plugin so it emits the numeric index, e.g. writeStanza(w, \"file-key\", \"0\")","Run the plugin binary manually with --age-plugin=identity-v1 to inspect what it actually prints","Check the plugin's stderr/log for a crash that garbled its stanza output"],"exampleFix":"// before (plugin side)\nwriteStanza(w, \"file-key\", idxLabel)\n// after\nwriteStanza(w, \"file-key\", strconv.Itoa(idx))","handlingStrategy":"validation","validationCode":"// Pre-check plugin behavior by running it in a harness before production use\ncmd := exec.Command(\"age-plugin-x\", \"--age-plugin=identity-v1\")","typeGuard":null,"tryCatchPattern":"_, err := identity.Unwrap(...)\nif err != nil && strings.Contains(err.Error(), \"malformed file-key stanza: invalid index\") {\n    return fmt.Errorf(\"plugin %s emitted non-numeric file-key index; upgrade plugin\", pluginName)\n}","preventionTips":["Use strconv.Itoa (not string formatting of arbitrary values) when writing plugin code","Verify plugin stdout is not interleaved with debug logs","Reproduce with the plugin binary run manually"],"tags":["go","age","plugin-protocol","stanza-parsing"],"backgroundTag":"plugin-protocol-violation","analyzedSha":"b74dce4cdbe35b5e5f66c06d9612b72f89028758","analyzedAt":"2026-08-31T23:59:31.627Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}