{"record":{"id":"ccac27cfbb3f86b6","repo":"jackwener/OpenCLI","slug":"label","errorCode":null,"errorMessage":"${label}","messagePattern":"\\$\\{label\\}","errorType":"validation","errorClass":"EmptyResultError","httpStatus":null,"severity":"info","filePath":"clis/_atlassian/shared.js","lineNumber":270,"sourceCode":"\nexport function requirePayloadArray(value, label) {\n    if (!Array.isArray(value)) {\n        throw new CommandExecutionError(`${label} returned an unexpected payload shape; expected an array.`);\n    }\n    return value;\n}\n\nexport function requirePayloadString(value, field, label) {\n    if (typeof value !== 'string' && typeof value !== 'number') {\n        throw new CommandExecutionError(`${label} did not include a stable ${field}.`);\n    }\n    const s = String(value).trim();\n    if (!s) throw new CommandExecutionError(`${label} did not include a stable ${field}.`);\n    return s;\n}\n\nexport function requireNonEmptyRows(rows, label, hint) {\n    if (!rows.length) throw new EmptyResultError(label, hint);\n    return rows;\n}\n\nexport function parseLimit(value, defaultValue = 20, maxValue = 100, label = 'limit') {\n    const raw = value ?? defaultValue;\n    const n = typeof raw === 'number' ? raw : Number(raw);\n    if (!Number.isInteger(n) || n <= 0) {\n        throw new ArgumentError(`${label} must be a positive integer`);\n    }\n    if (n > maxValue) {\n        throw new ArgumentError(`${label} must be <= ${maxValue}`);\n    }\n    return n;\n}\n\nexport function requireExecute(args, commandName) {\n    if (args.execute !== true) {\n        throw new ArgumentError(`${commandName} requires --execute to perform a remote write`);","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/_atlassian/shared.js#L252-L288","documentation":"requireNonEmptyRows delegates to EmptyResultError(label, hint): the query executed successfully but returned zero rows. This is a signal, not a failure — the CLI surfaces it distinctly (with a hint) so scripts can tell 'no matches' apart from 'bad query'.","triggerScenarios":"A search whose CQL/JQL matches nothing; listing pages in an empty space; filtering by a label/macro that no content uses; permissions hiding all matching content from the authenticated user.","commonSituations":"Typo'd space key or label; searching the wrong site/instance; content archived or in trash so it's excluded from results; restricted pages invisible to the API token's user.","solutions":["Relax or correct the query (CQL/JQL) — verify space keys, labels, and date ranges.","Confirm the content exists and isn't in trash/archived.","Check permissions: the API user may not see the matching pages/issues.","Handle EmptyResultError in scripts so empty results don't crash pipelines."],"exampleFix":"# before (overly restrictive query)\nopencli confluence search --cql 'label = \"q3-okr\" AND space = DEV'\n# after — verify stepwise\nopencli confluence search --cql 'space = DEV'   # then add filters","handlingStrategy":"try-catch","validationCode":"// sanity-check the query before running\nif (!cql || !cql.trim()) throw new Error('CQL query is empty');\nconst spaceKey = 'DEV';\nif (spaceKey.length < 2) console.warn('Space key looks too short — verify it');","typeGuard":null,"tryCatchPattern":"try {\n  const rows = await searchCmd(args);\n} catch (e) {\n  if (e instanceof EmptyResultError || /no results/i.test(e.message)) {\n    console.warn('No matching content — relaxing query or checking permissions.');\n    return [];\n  }\n  throw e;\n}","preventionTips":["Test CQL/JQL queries in the web UI before scripting them.","Confirm space keys, labels, and permissions for the API user.","Remember trash/archived content is excluded from search.","Treat empty results as data, not errors, in pipelines."],"tags":["empty-result","search","query","atlassian"],"backgroundTag":"empty-result-set","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}