{"record":{"id":"f68af9a5114f3034","repo":"jackwener/OpenCLI","slug":"time-must-be-one-of-d-w-m-or-y","errorCode":null,"errorMessage":"--time must be one of d, w, m, or y","messagePattern":"--time must be one of d, w, m, or y","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/duckduckgo/search.js","lineNumber":96,"sourceCode":"  strategy: Strategy.PUBLIC,\n  browser: true,\n  args: [\n    { name: 'keyword', positional: true, required: true, help: 'Search query' },\n    { name: 'limit', type: 'int', default: 10, help: 'Number of results per page (1-10). For multi-page, use --offset' },\n    { name: 'offset', type: 'int', default: 0, help: 'Result offset for pagination (0, 10, 20...). Uses XHR POST internally' },\n    { name: 'region', help: 'Region code (e.g. jp-jp, us-en, cn-zh). Default: all regions' },\n    { name: 'time', help: 'Time range: d (day), w (week), m (month), y (year)' },\n  ],\n  columns: ['rank', 'title', 'url', 'snippet', 'displayUrl', 'icon', 'resultType'],\n  func: async (page, kwargs) => {\n    const limit = requireBoundedInteger(kwargs.limit, 10, 1, 10, '--limit');\n    const keyword = requireSearchQuery(kwargs.keyword);\n    const offset = requireNonNegativeInteger(kwargs.offset, 0, '--offset');\n    if (offset % 10 !== 0) {\n      throw new ArgumentError('--offset must be a multiple of 10 for DuckDuckGo HTML pagination');\n    }\n    if (kwargs.time && !/^(d|w|m|y)$/.test(String(kwargs.time))) {\n      throw new ArgumentError('--time must be one of d, w, m, or y');\n    }\n    let url = `https://html.duckduckgo.com/html/?q=${encodeURIComponent(keyword)}`;\n    if (kwargs.region) url += `&kl=${encodeURIComponent(String(kwargs.region))}`;\n    if (kwargs.time) url += `&df=${encodeURIComponent(String(kwargs.time))}`;\n    await runBrowserStep('duckduckgo search navigation', () => page.goto(url));\n    try {\n      await page.wait({ selector: '.result', timeout: 8 });\n    } catch {\n      await page.wait(3).catch(function() {});\n    }\n    var raw;\n    if (offset === 0) {\n      raw = await runBrowserStep('duckduckgo search extraction', () => page.evaluate(buildExtractorJs(limit)));\n    } else {\n      raw = await runBrowserStep('duckduckgo search pagination extraction', () => page.evaluate(buildPaginateJs(limit, keyword, offset, kwargs.region)));\n    }\n    const rows = requireRows(raw, 'duckduckgo search');\n    if (rows.length === 0) {","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/duckduckgo/search.js#L78-L114","documentation":"The DuckDuckGo search command's optional --time filter maps to DuckDuckGo's df (date filter) parameter, which only accepts d (day), w (week), m (month), or y (year). Any other value fails a regex check and an ArgumentError is thrown before navigation.","triggerScenarios":"Passing --time values like 'day', '24h', 'month', '1w', or a full date string instead of the single letters d, w, m, or y.","commonSituations":"Copying time-filter syntax from Google/Bing APIs into DuckDuckGo; writing 'week' instead of 'w'; scripts building the flag from user input without normalizing it.","solutions":["Use exactly d, w, m, or y for --time","Map verbose inputs ('day' -> 'd', 'month' -> 'm') before invoking","Add a whitelist check on user input before passing it to the command","Catch ArgumentError to give the user the accepted values"],"exampleFix":"// before\nawait ddgSearch({ keyword: 'cats', time: 'past week' });\n// after\nawait ddgSearch({ keyword: 'cats', time: 'w' });","handlingStrategy":"validation","validationCode":"const TIME_VALUES = ['d', 'w', 'm', 'y'];\nif (time && !TIME_VALUES.includes(String(time))) {\n  throw new Error('--time must be one of d, w, m, y');\n}","typeGuard":"function isValidTime(t) {\n  return t == null || ['d', 'w', 'm', 'y'].includes(String(t));\n}","tryCatchPattern":null,"preventionTips":["Expose only the four letter values in your own UI/CLI wrapper","Map verbose words ('day','week','month','year') to d/w/m/y before calling","Never pass raw user strings straight into --time"],"tags":["argument-validation","cli","input-validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}