jackwener/OpenCLI · error · CommandExecutionError

Flomo API returned a memo without slug/id

Error message

Flomo API returned a memo without slug/id

What it means

normalizeMemo requires every memo entry to carry a usable identifier, read as `memo.slug || memo.id`. If both are missing or empty after string conversion and trim, this error is thrown because the CLI cannot build the memo's id or its URL (https://v.flomoapp.com/mine/?memo_id=...). It signals that the API returned memo objects lacking the identifier fields this CLI relies on.

Source

Thrown at clis/flomo/memos.js:131

  if (!Array.isArray(files)) return '';
  return files
    .map((file) => file?.thumbnail_url || file?.url || '')
    .map((url) => String(url).trim())
    .filter(Boolean)
    .join(' | ');
}

function memoUrl(slug) {
  return slug ? `https://${FLOMO_APP_DOMAIN}/mine/?memo_id=${encodeURIComponent(slug)}` : '';
}

function normalizeMemo(memo) {
  if (!memo || typeof memo !== 'object' || Array.isArray(memo)) {
    throw new CommandExecutionError('Flomo API returned a malformed memo entry');
  }
  const slug = String(memo.slug || memo.id || '').trim();
  if (!slug) {
    throw new CommandExecutionError('Flomo API returned a memo without slug/id');
  }
  return {
    id: slug,
    url: memoUrl(slug),
    content: String(memo.content || '').trim(),
    slug,
    tags: normalizeTags(memo.tags),
    images: normalizeImages(memo.files),
    created_at: String(memo.created_at || ''),
    updated_at: String(memo.updated_at || ''),
  };
}

async function fetchFlomoJson(url, token) {
  let resp;
  try {
    resp = await fetch(url, {
      headers: {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Update the opencli package to the latest version to pick up schema changes for the Flomo API.
  2. Re-authenticate / reload the Flomo session so the CLI reads fresh, complete data instead of stale partial records.
  3. Check Flomo web UI for memos that appear corrupted or incomplete and try narrowing results with --since or --limit.
  4. If it persists, capture the raw API response and file an issue with the offending memo shape.

Example fix

// before
normalizeMemo({ content: 'no identifier here' }); // throws
// after: caller-side guard so the CLI never sees an unidentifiable memo
const ok = body.data.filter((m) => m && typeof m === 'object' && String(m.slug || m.id || '').trim());
console.warn(`skipped ${body.data.length - ok.length} memos without slug/id`);
rows = ok.map(normalizeMemo);
Defensive patterns

Strategy: type-guard

Validate before calling

const missing = body.data
  .map((m, i) => [i, m && String(m.slug || m.id || '').trim()])
  .filter(([, id]) => !id)
  .map(([i]) => i);
if (missing.length) console.warn(`memos without slug/id at indices: ${missing.join(', ')}`);

Type guard

function hasMemoId(memo) {
  return memo !== null &&
    typeof memo === 'object' && !Array.isArray(memo) &&
    String(memo.slug || memo.id || '').trim().length > 0;
}
const safeRows = body.data.filter(hasMemoId).map(normalizeMemo);

Try / catch

try {
  rows = body.data.map(normalizeMemo);
} catch (err) {
  if (err.message.includes('without slug/id')) {
    console.error('Some memos lack identifiers; filter with hasMemoId() or update opencli.');
  } else { throw err; }
}

Prevention

When it happens

Trigger: Calling `flomo memos` when a memo object in body.data has no slug and no id field (both undefined or empty strings); Flomo renaming the identifier field in their internal API; memos created by newer clients that use a different id key.

Common situations: Flomo app update changing the memo schema; memos synced in a partial state missing identifiers; outdated CLI version incompatible with the current undocumented API; third-party API mocks returning incomplete memo fixtures.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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