jackwener/OpenCLI · error · CommandExecutionError

Youdao note parser did not extract a title

Error message

Youdao note parser did not extract a title

What it means

normalizeExtractionResult validates the payload returned by the in-page Youdao note extractor before building the output row. The page store must supply a note title; if `title` is falsy the result is considered unusable and a CommandExecutionError is thrown rather than emitting a row with an empty title.

Source

Thrown at clis/youdao/note.js:198

    if (reason === 'auth') {
      throw new AuthRequiredError('note.youdao.com', 'Youdao shared note requires login or additional permission');
    }
    if (reason === 'not_found') {
      throw new EmptyResultError('youdao note', 'The shared note is missing, expired, cancelled, or inaccessible.');
    }
    throw new CommandExecutionError(`Youdao note parser failed: ${reason}`);
  }
  const title = String(data[1] ?? '');
  const content = String(data[2] ?? '');
  const summary = String(data[3] ?? '');
  const keywords = String(data[4] ?? '');
  const createTime = data[5];
  const fileSize = data[6];
  const hasContentField = data[7] === true;
  const rawContentLength = Number(data[8] ?? 0);
  const finalUrl = String(data[9] || sourceUrl);
  if (!title) {
    throw new CommandExecutionError('Youdao note parser did not extract a title');
  }
  if (!hasContentField) {
    throw new CommandExecutionError('Youdao note parser did not find full note content in the page store');
  }
  if (rawContentLength > 0 && !content) {
    throw new CommandExecutionError('Youdao note parser found note content but extracted no readable text');
  }
  const row = {};
  row.title = title;
  row.content = content;
  row.summary = summary;
  row.keywords = keywords;
  row.created_at = formatYoudaoTimestamp(createTime);
  row.file_size = fileSize == null ? '' : String(fileSize);
  row.url = finalUrl;
  return row;
}

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Open the URL in a real browser and confirm the note loads and shows a title
  2. Verify the extractor script (buildExtractorJs) still matches Youdao's current DOM/title markup and update selectors
  3. Ensure page.goto + wait completed before evaluate so the page store is populated
  4. Add a fallback title (e.g. first heading or file name) in the extractor payload before normalization

Example fix

// before
const title = payload.title;
// after
const title = payload.title || payload.raw?.fileName || payload.raw?.subject || 'Untitled Youdao note';
Defensive patterns

Strategy: validation

Validate before calling

if (!payload || payload.title == null || String(payload.title).trim() === '') {
  throw new Error('Extractor payload has no title; aborting before normalizeExtractionResult');
}

Type guard

function hasTitle(p) {
  return typeof p === 'object' && p !== null && typeof p.title === 'string' && p.title.trim().length > 0;
}

Try / catch

try {
  const row = await cli.youdao.note({ url });
} catch (e) {
  if (/did not extract a title/.test(e.message)) {
    console.error('Note page did not yield a title; check the URL or update extractor selectors');
  } else throw e;
}

Prevention

When it happens

Trigger: The browser-side extractor ran but its payload contained an empty/missing title field — e.g. the shared note page rendered an error/interstitial instead of the note, the extractor's title selectors matched nothing, or the note genuinely has no title and the extractor did not fall back to a default.

Common situations: Sharing links that expired or were deleted; scraping before the SPA hydrated the page store; Youdao changed DOM markup so the title selector breaks; region/login wall showing a generic page.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/8cc9344b2ccc9199. Report an issue: GitHub.