tinyhumansai/openhuman · error · Error
provider-chain row ${p.order} must not contain a "|" charact
Error message
provider-chain row ${p.order} must not contain a "|" character What it means
parseProviderChain() rejects any row whose component name or role text contains `|`, because the rendered output is a markdown table and a pipe would break or inject columns. This runs on both p.name and p.role after parsing, so the pipe can be on either side of the em dash.
Source
Thrown at scripts/generate-architecture-docs.mjs:79
const m = rowRe.exec(line);
if (!m) continue;
providers.push({ order: Number(m[1]), name: m[2].trim(), role: m[3].trim() });
}
if (providers.length === 0) {
throw new Error('provider-chain source marker contained no `N. Component — role` rows');
}
// Guard against drift in the marker itself: orders must be 1..N, in order,
// names non-empty, and roles free of the `|` that would break the table.
providers.forEach((p, i) => {
if (p.order !== i + 1) {
throw new Error(
`provider-chain rows must be numbered 1..N in order; row ${i + 1} is numbered ${p.order}`
);
}
if (!p.name) throw new Error(`provider-chain row ${p.order} is missing a component name`);
if (!p.role) throw new Error(`provider-chain row ${p.order} is missing a role`);
if (p.name.includes('|') || p.role.includes('|')) {
throw new Error(`provider-chain row ${p.order} must not contain a "|" character`);
}
});
return providers;
}
/**
* Render the markdown body that lives between the BEGIN/END markers.
* Returned as an array of lines (no trailing join) so splicing stays
* deterministic and line-oriented.
*
* @param {{ order: number, name: string, role: string }[]} providers
* @returns {string[]}
*/
export function renderProviderChainBody(providers) {
return [
'',
'_Generated from `app/src/App.tsx` by `scripts/generate-architecture-docs.mjs`. ' +
'Do not edit by hand — run `pnpm docs:generate` to refresh._',View on GitHub (pinned to a221052e0d)
Solutions
- Replace the `|` in the flagged row with `/`, `or`, or a comma
- If the pipe is essential (command syntax), move that detail to prose outside the marker block
- Re-run the generator; the table renders with intact columns
Example fix
// before: * 9. socketService — keeps socketService | MCP transport aligned // after: * 9. socketService — keeps socketService and MCP transport aligned
Defensive patterns
Strategy: validation
Validate before calling
for (const m of rows.map(l => ROW_RE.exec(l))) {
if (m[2].includes('|') || m[3].includes('|')) {
console.error(`Row ${m[1]} contains a pipe — replace '|' with '/' or 'or'`);
process.exit(1);
}
} Prevention
- Never use `|` shorthand in marker rows — write 'and' or '/' (the rendered artifact is a markdown table)
- Keep command-syntax snippets out of the role column; put them in prose outside the markers
When it happens
Trigger: Writing shorthand like `* 7. layout | theme — split state` or a role like `proxies socket | MCP traffic`; even a single `|` anywhere in either field throws with the row number.
Common situations: Describing dual responsibility with a pipe ('A | B'); pasting CLI usage text (e.g. `--flags | jq`) into a role description.
Related errors
- generated-block END marker must come after the BEGIN marker
- provider-chain rows must be numbered 1..N in order; row ${i
- provider-chain row ${p.order} is missing a component name
- generated-block markers not found in ${FRONTEND_DOC}; expect
- provider-chain source marker not found in App.tsx; expected
AI-assisted analysis of tinyhumansai/openhuman@a221052e0d (2026-08-16).
Data as JSON: /api/errors/c0213bf367978024.
Report an issue: GitHub.