DIYgod/RSSHub · error · Error

Unknown placeholder type: ${placeholder?.type} in ${link}

Error message

Unknown placeholder type: ${placeholder?.type} in ${link}

What it means

AFR article HTML embeds <x-placeholder> elements that renderArticle replaces for known types (markup, scribd, twitter, …). An unknown placeholder type triggers a generic `Error` with the placeholder type and the article link.

Source

Thrown at lib/routes/afr/utils.ts:76

            case 'linkExternal':
                $el.replaceWith(`<a href="${placeholder.data.url}" target="_blank" rel="noopener">${placeholder.data.text}</a>`);
                break;

            case 'quote':
                $el.replaceWith(placeholder.data.markup);
                break;

            case 'scribd':
                $el.replaceWith(`<a href="${placeholder.data.url}" target="_blank" rel="noopener">View on Scribd</a>`);
                break;

            case 'twitter':
                $el.replaceWith(`<a href="${placeholder.data.url}">${placeholder.data.url}</a>`);
                break;

            default:
                throw new Error(`Unknown placeholder type: ${placeholder?.type} in ${link}`);
        }
    });

    return $.html();
};

View on GitHub (pinned to bed535e087)

Solutions

  1. Report the placeholder.type and link to maintainers so a new case can be added.
  2. As a maintainer, add a new case to the switch and emit a sensible replacement (link or markup).
  3. Short-term, default to replacing unknown placeholders with empty string rather than throwing.

Example fix

// before
default:
    throw new Error(`Unknown placeholder type: ${placeholder?.type} in ${link}`);
// after
default:
    $el.replaceWith(placeholder?.data?.url ? `<a href="${placeholder.data.url}">${placeholder.data.url}</a>` : '');
Defensive patterns

Strategy: type-guard

Validate before calling

const KNOWN_PLACEHOLDER_TYPES = new Set(['markup','scribd','twitter']);
function knownAfrPlaceholder(t) {
  return t == null || KNOWN_PLACEHOLDER_TYPES.has(t);
}

Type guard

function isKnownAfrPlaceholderType(t): t is 'markup'|'scribd'|'twitter'|undefined {
  return t === undefined || t === 'markup' || t === 'scribd' || t === 'twitter';
}

Try / catch

try {
  return renderArticle(asset, link);
} catch (e) {
  if (e instanceof Error && /Unknown placeholder type/.test(e.message)) {
    // strip unknown placeholders and retry, rather than failing the article
    return asset.body.replace(/<x-placeholder[^>]*>[\s\S]*?<\/x-placeholder>/g, '');
  }
  throw e;
}

Prevention

When it happens

Trigger: AFR adds a new embed/placeholder type to article HTML (e.g. a new social platform, an iframe widget) that the switch does not yet cover.

Common situations: Upstream adds a new embeddable block; an article uses a feature not previously seen in the feed.

Related errors


AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12). Data as JSON: /api/errors/bc1685d010f82ab7. Report an issue: GitHub.