{"record":{"id":"61f21a0006de06e0","repo":"jackwener/OpenCLI","slug":"label-did-not-include-a-stable-text-value-61f21a","errorCode":null,"errorMessage":"${label} did not include a stable text value.","messagePattern":"(.+?) did not include a stable text value\\.","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/dongchedi/utils.js","lineNumber":133,"sourceCode":"export function requireArray(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 requireStableId(value, label) {\n    const id = String(value ?? '').trim();\n    if (!/^\\d+$/.test(id) || id === '0') {\n        throw new CommandExecutionError(`${label} did not include a stable numeric id.`);\n    }\n    return id;\n}\n\nexport function requireText(value, label) {\n    const text = clean(value);\n    if (!text) {\n        throw new CommandExecutionError(`${label} did not include a stable text value.`);\n    }\n    return text;\n}\n\n/** Rescale a Dongchedi x100 score int (422) to a /5 float (4.22). */\nexport function parseScore(raw) {\n    const n = Number(raw);\n    if (!Number.isFinite(n) || n <= 0) return null;\n    return Number((n / 100).toFixed(2));\n}\n\n/**\n * Normalize a series id argument: a bare number, or a\n * `https://www.dongchedi.com/auto/series/<id>` URL.\n */\nexport function normalizeSeriesId(rawInput) {\n    const raw = String(rawInput || '').trim();\n    if (!raw) throw new ArgumentError('series_id must be a non-empty value');","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/dongchedi/utils.js#L115-L151","documentation":"A CommandExecutionError thrown by requireText (clis/dongchedi/utils.js:133), called by parseKoubei and parseModels (name/fields extraction). It fires when a text field that must be non-empty (e.g. a model name or review field) is missing, null, or whitespace-only after cleaning. The library refuses to emit rows with unstable/blank identifying text.","triggerScenarios":"Parsing entries whose `name` or required text field is empty: pre-release cars listed without names, koubei entries with stripped/hidden user or car fields, or a Dongchedi schema change renaming the text key so the parser reads undefined.","commonSituations":"Freshly published models not yet given display names; reviews where the platform redacted the reviewer or car; a redeploy moving `name` to a localized/nested key.","solutions":["Inspect the live pageProps entry to locate the current key holding the display text and update the parser.","Skip entries with genuinely missing names (pre-release/placeholder items) before calling requireText.","Catch CommandExecutionError and drop the row with a log noting which label lacked text.","Update test fixtures so required text fields match the real non-empty SSR values."],"exampleFix":"// before\nconst name = requireText(model.name, 'model name'); // throws when name is blank\n// after\nif (!clean(model.name)) continue; // skip unnamed placeholder entries\nconst name = requireText(model.name, 'model name');","handlingStrategy":"validation","validationCode":"function hasText(v) {\n  return String(v ?? '').replace(/\\s+/g, ' ').trim().length > 0;\n}","typeGuard":null,"tryCatchPattern":"try {\n  const name = requireText(model.name, 'model name');\n} catch (err) {\n  if (err instanceof CommandExecutionError && /stable text value/.test(err.message)) {\n    skipRow(model, 'missing name'); // drop placeholder rows gracefully\n  } else throw err;\n}","preventionTips":["Skip entries with blank names/fields before calling requireText.","Update parser key paths if display text moves to a nested/localized key.","Treat redacted review fields as skippable, not fatal.","Keep fixtures' required text fields non-empty like real payloads."],"tags":["schema-validation","missing-field","parsing","dongchedi"],"backgroundTag":"missing-required-field","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}