{"record":{"id":"875c33b73ffd34e6","repo":"jackwener/OpenCLI","slug":"pubmed-year-from-must-be-year-to-875c33","errorCode":null,"errorMessage":"pubmed year-from must be <= year-to","messagePattern":"pubmed year-from must be <= year-to","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"warning","filePath":"clis/pubmed/journal.js","lineNumber":40,"sourceCode":"        { name: 'journal', positional: true, required: true, help: 'Journal name, e.g. \"Nature\" or \"The Lancet\"' },\n        { name: 'limit', type: 'int', default: 20, help: 'Max results (1-100)' },\n        { name: 'year-from', type: 'int', help: 'Filter publication year from' },\n        { name: 'year-to', type: 'int', help: 'Filter publication year to' },\n        { name: 'sort', default: 'relevance', choices: ['relevance', 'date'], help: 'Sort by relevance or date' },\n    ],\n    columns: SEARCH_COLUMNS,\n    func: async (args) => {\n        const journal = requireText(args.journal, 'journal');\n        const limit = requireBoundedInt(args.limit, 20, 100);\n        const yearFrom = requireYear(args['year-from'], 'year-from');\n        const yearTo = requireYear(args['year-to'], 'year-to');\n        const sort = requireChoice(args.sort, ['relevance', 'date'], 'sort', 'relevance');\n        const terms = [`${journal}[Journal]`];\n        if (yearFrom || yearTo) {\n            const from = yearFrom || 1800;\n            const to = yearTo || new Date().getFullYear();\n            if (from > to) {\n                throw new ArgumentError('pubmed year-from must be <= year-to');\n            }\n            terms.push(`${from}:${to}[PDAT]`);\n        }\n        const esearch = await eutilsFetch('esearch', {\n            term: terms.join(' AND '),\n            retmax: limit,\n            usehistory: 'y',\n            sort: sort === 'date' ? 'pub_date' : '',\n        }, { label: 'pubmed journal' });\n        const pmids = esearch?.esearchresult?.idlist;\n        if (!Array.isArray(pmids)) {\n            throw new CommandExecutionError('pubmed journal did not return an id list', 'PubMed ESearch response shape may have changed.');\n        }\n        if (pmids.length === 0) {\n            throw new EmptyResultError('pubmed journal', `No articles found for journal \"${journal}\".`);\n        }\n        return fetchSummaryRows(pmids, 'pubmed journal summary');\n    },","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/pubmed/journal.js#L22-L58","documentation":"This ArgumentError is thrown by the `pubmed journal` command when the optional `--year-from` value is greater than `--year-to`. The command builds a PubMed [PDAT] date-range query and refuses to send a malformed range to the NCBI E-utilities API. It is an input-validation error, not a network failure.","triggerScenarios":"Running the journal command with yearFrom later than yearTo, e.g. `--year-from 2023 --year-to 2019`. Also occurs when only one of the two is set and defaults collide: yearFrom=2050 with no yearTo (to defaults to current year), or yearTo=1800 with no yearFrom (from defaults to 1800).","commonSituations":"Typo swapping the from/to flags on the command line; scripting that passes user-supplied years unvalidated; passing a future year as year-from; accidentally passing year-to into year-from.","solutions":["Swap the values so year-from <= year-to before invoking the command","Clamp or validate user-supplied years in your script (e.g. from <= to, both 4-digit years within 1800..current year)","Pass only one of the two flags if you just want articles from a year onwards or up to a year"],"exampleFix":"// before\nclis.pubmedJournal({ journal: 'Nature', yearFrom: 2023, yearTo: 2018 });\n// after\nconst from = Math.min(2023, 2018), to = Math.max(2023, 2018);\nclis.pubmedJournal({ journal: 'Nature', yearFrom: from, yearTo: to });","handlingStrategy":"validation","validationCode":"function validateYearRange(yearFrom, yearTo) {\n  const now = new Date().getFullYear();\n  const from = yearFrom ?? 1800;\n  const to = yearTo ?? now;\n  if (!Number.isInteger(from) || !Number.isInteger(to)) throw new TypeError('years must be integers');\n  if (from < 1800 || to > now) throw new RangeError('years out of range');\n  if (from > to) throw new RangeError(`year-from (${from}) must be <= year-to (${to})`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await clis.pubmedJournal({ journal, yearFrom, yearTo });\n} catch (e) {\n  if (e.name === 'ArgumentError' && /year-from/.test(e.message)) {\n    [yearFrom, yearTo] = [yearTo, yearFrom]; // or surface a friendly message\n  } else throw e;\n}","preventionTips":["Always validate from <= to in CLI wrappers before calling the command","Default missing bounds the same way the library does (1800 / current year) when previewing","Swap values instead of erroring when order does not matter to your UX","Unit-test year-range inputs including edge years (1800, future years)"],"tags":["validation","input-error","pubmed","date-range"],"backgroundTag":"invalid-date-range","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}