Summary
clip() in src/api.ts hands Defuddle the document element instead of the document. Defuddle returns an empty result for that input, so the CLI writes a note with every field blank — no error, no warning, exit code 0.
This is, I believe, the root cause of #745 (CLI: empty output and navigator error), which was closed as "the feature is still in progress". The navigator is not defined half of that report is separate; this issue is only about the silent empty output.
Reproduce
git clone --depth 1 https://github.com/obsidianmd/obsidian-clipper.git
cd obsidian-clipper && npm install && npm run build:cli
cat > /tmp/t.json <<'JSON'
{
"schemaVersion": "0.1.0",
"name": "min",
"behavior": "create",
"noteNameFormat": "{{title}}",
"path": "Clippings",
"noteContentFormat": "{{content}}",
"properties": [
{"name": "title", "value": "{{title}}", "type": "text"},
{"name": "words", "value": "{{words}}", "type": "number"}
]
}
JSON
node dist/cli.cjs "https://en.wikipedia.org/wiki/Markdown" -t /tmp/t.json -o /tmp/out.md
Actual — 115 bytes, all fields empty:
Expected — title: "Markdown", words: 2671, ~33 KB of body.
Not URL-specific. Same result with --html on a locally saved page, and with MDN, so it is not a fetch or SPA problem.
Cause
src/api.ts:
const documentElement = doc.documentElement || doc;
const defuddle = new DefuddleClass(documentElement as unknown as Document, { url });
Defuddle expects a Document. With linkedom, doc.documentElement is truthy, so an HTMLHtmlElement is passed and parsing yields nothing. Direct check against defuddle@0.19.2 + linkedom@0.18:
document => title: "Markdown" words: 2671 contentLen: 47204
documentElement => title: "" words: 0 contentLen: 0
The browser extension is unaffected because popup.ts does not go through api.ts.
Fix
- const defuddle = new DefuddleClass(documentElement as unknown as Document, { url });
+ const defuddle = new DefuddleClass(doc as unknown as Document, { url });
With that one line, the reproduction above yields title: "Markdown", words: 2671, 33 KB body. The documentElement local becomes unused and can be dropped.
I'd also suggest treating an empty Defuddle result as an error rather than writing the note — a blank note that lands silently is worse than a failure, especially for scripted use.
Environment
obsidian-clipper main (package version 1.7.1), built via npm run build:cli
- Node v22.22.2, npm 10.9.7, Linux
defuddle 0.19.2, linkedom 0.18.x
Summary
clip()insrc/api.tshands Defuddle the document element instead of the document. Defuddle returns an empty result for that input, so the CLI writes a note with every field blank — no error, no warning, exit code 0.This is, I believe, the root cause of #745 (CLI: empty output and navigator error), which was closed as "the feature is still in progress". The
navigator is not definedhalf of that report is separate; this issue is only about the silent empty output.Reproduce
Actual — 115 bytes, all fields empty:
Expected —
title: "Markdown",words: 2671, ~33 KB of body.Not URL-specific. Same result with
--htmlon a locally saved page, and with MDN, so it is not a fetch or SPA problem.Cause
src/api.ts:Defuddle expects a
Document. With linkedom,doc.documentElementis truthy, so anHTMLHtmlElementis passed and parsing yields nothing. Direct check againstdefuddle@0.19.2+linkedom@0.18:The browser extension is unaffected because
popup.tsdoes not go throughapi.ts.Fix
With that one line, the reproduction above yields
title: "Markdown",words: 2671, 33 KB body. ThedocumentElementlocal becomes unused and can be dropped.I'd also suggest treating an empty Defuddle result as an error rather than writing the note — a blank note that lands silently is worse than a failure, especially for scripted use.
Environment
obsidian-clippermain(package version 1.7.1), built vianpm run build:clidefuddle0.19.2,linkedom0.18.x