{"record":{"id":"fba7f24649d2594f","repo":"FiloSottile/age","slug":"user-cancelled-prompt","errorCode":null,"errorMessage":"user cancelled prompt","messagePattern":"user cancelled prompt","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"plugin/tui.go","lineNumber":68,"sourceCode":"\t\t\t\t_, err := term.ReadSecret(message)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn false, err\n\t\t\t\t}\n\t\t\t\treturn true, nil\n\t\t\t}\n\t\t\tmessage += fmt.Sprintf(\" (press [1] for %q or [2] for %q)\", yes, no)\n\t\t\tfor {\n\t\t\t\tselection, err := term.ReadCharacter(message)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn false, err\n\t\t\t\t}\n\t\t\t\tswitch selection {\n\t\t\t\tcase '1':\n\t\t\t\t\treturn true, nil\n\t\t\t\tcase '2':\n\t\t\t\t\treturn false, nil\n\t\t\t\tcase '\\x03': // CTRL-C\n\t\t\t\t\treturn false, errors.New(\"user cancelled prompt\")\n\t\t\t\tdefault:\n\t\t\t\t\twarningf(\"reading value for age-plugin-%s: invalid selection %q\", name, selection)\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tWaitTimer: func(name string) {\n\t\t\tprintf(\"waiting on %s plugin...\", name)\n\t\t},\n\t}\n}\n","sourceCodeStart":50,"sourceCodeEnd":79,"githubUrl":"https://github.com/FiloSottile/age/blob/b74dce4cdbe35b5e5f66c06d9612b72f89028758/plugin/tui.go#L50-L79","documentation":"In the plugin's interactive TUI confirm prompt, pressing CTRL-C (byte 0x03) aborts the prompt. The code converts that keypress into the error \"user cancelled prompt\" so the plugin/client knows the user declined to proceed. This is intentional cancellation, not a malfunction.","triggerScenarios":"User presses CTRL-C while the age-plugin-<name> TUI confirmation dialog (yes/no selection) is displayed.","commonSituations":"Users aborting an interactive passphrase/consent prompt during age encryption with a plugin; scripted runs where the user sees the prompt and interrupts it.","solutions":["Treat this error as normal cancellation in the client: abort the operation quietly without reporting it as a failure.","Detect errors.Is(err, ...) or match the message to distinguish user cancel from real errors.","If prompts must not be interruptible in automation, provide input non-interactively per the plugin's documented protocol."],"exampleFix":"// before\nif err != nil { return err } // surfaces cancel as a scary failure\n// after\nif err != nil {\n    if strings.Contains(err.Error(), \"user cancelled prompt\") {\n        return errPluginCancelled\n    }\n    return err\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err != nil {\n    if strings.Contains(err.Error(), \"user cancelled prompt\") {\n        return nil // or a sentinel cancel error\n    }\n    return err\n}","preventionTips":["Treat cancellation as a distinct, expected outcome in plugin clients.","Document CTRL-C behavior for users of interactive prompts.","Provide non-interactive input paths for automation to avoid prompts entirely."],"tags":["plugin","tui","user-input"],"backgroundTag":"user-cancelled-prompt","analyzedSha":"b74dce4cdbe35b5e5f66c06d9612b72f89028758","analyzedAt":"2026-08-31T23:59:31.627Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}