{"record":{"id":"e72dcefd9d1a3b0c","repo":"jackwener/OpenCLI","slug":"argument-e72dce","errorCode":"ARGUMENT","errorMessage":"An email address is required.","messagePattern":"An email address is required\\.","errorType":"validation","errorClass":"CliError","httpStatus":null,"severity":"error","filePath":"clis/paperreview/submit.js","lineNumber":35,"sourceCode":"        { name: 'prepare-only', type: 'bool', default: false, help: 'Request an upload slot but stop before uploading the PDF' },\n        { name: 'timeout', type: 'int', required: false, default: 120, help: 'Max seconds for the overall command (default: 120)' },\n    ],\n    columns: ['status', 'file', 'email', 'venue', 'token', 'review_url', 'message'],\n    footerExtra: (kwargs) => {\n        if (kwargs['dry-run'] === true)\n            return 'dry run only';\n        if (kwargs['prepare-only'] === true)\n            return 'prepared only';\n        return undefined;\n    },\n    func: async (kwargs) => {\n        const pdfFile = await readPdfFile(kwargs.pdf);\n        const email = String(kwargs.email ?? '').trim();\n        const venue = normalizeVenue(kwargs.venue);\n        const dryRun = kwargs['dry-run'] === true;\n        const prepareOnly = kwargs['prepare-only'] === true;\n        if (!email) {\n            throw new CliError('ARGUMENT', 'An email address is required.', 'Pass --email <address>');\n        }\n        if (dryRun) {\n            return summarizeSubmission({\n                pdfFile,\n                email,\n                venue,\n                message: 'Input validation passed. No remote request was sent.',\n                dryRun: true,\n            });\n        }\n        const { response: uploadUrlResponse, payload: uploadUrlPayload } = await requestJson('/api/get-upload-url', {\n            method: 'POST',\n            headers: { 'Content-Type': 'application/json' },\n            body: JSON.stringify({\n                filename: pdfFile.fileName,\n                venue,\n            }),\n        });","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/paperreview/submit.js#L17-L53","documentation":"The paperreview `submit` command needs an email address for the submission payload. The CLI trims kwargs.email and throws CliError with code ARGUMENT (with hint 'Pass --email <address>') when it is empty. The check happens after the PDF is read but before any submission proceeds.","triggerScenarios":"Running submit without --email, or with an empty/whitespace-only value.","commonSituations":"Forgetting the flag on first use; scripts with unset EMAIL variables; confusing --dry-run/--prepare-only flows where email still must be supplied.","solutions":["Re-run with --email you@example.com as the hint suggests.","Validate the email variable in wrapper scripts before calling the CLI.","Note email is required even for --dry-run/--prepare-only since it is part of the prepared payload."],"exampleFix":"// before\ncli submit --pdf paper.pdf\n// after\ncli submit --pdf paper.pdf --email author@example.com","handlingStrategy":"validation","validationCode":"const email = process.env.SUBMIT_EMAIL;\nif (!email || !/^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$/.test(email.trim())) {\n  throw new Error('Provide a valid --email address');\n}","typeGuard":"function isEmail(v) {\n  return typeof v === 'string' && /^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$/.test(v.trim());\n}","tryCatchPattern":"try {\n  await cli.submit({ pdf: pdfPath, email: '' });\n} catch (err) {\n  if (err.code === 'ARGUMENT' && /email/i.test(err.message)) console.error('Pass --email <address>');\n  else throw err;\n}","preventionTips":["Always include --email even for --dry-run/--prepare-only.","Validate the email format in wrapper scripts.","Set a default email in CI config and assert it exists."],"tags":["cli","validation","missing-argument"],"backgroundTag":"missing-required-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}